summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Di Meglio <fdimeglio@google.com>2012-06-25 15:49:11 -0700
committerFabrice Di Meglio <fdimeglio@google.com>2012-07-12 17:39:12 -0700
commitcf1ba0298c48ae56608ed556dc715eb69c54f9b9 (patch)
tree4f0b83de4bb8585506fed122a215757e87503754
parent92bd5f95ca078a795db7c2efd30e85d4260561de (diff)
downloadframeworks_base-cf1ba0298c48ae56608ed556dc715eb69c54f9b9.zip
frameworks_base-cf1ba0298c48ae56608ed556dc715eb69c54f9b9.tar.gz
frameworks_base-cf1ba0298c48ae56608ed556dc715eb69c54f9b9.tar.bz2
Make ActionBar aware of layout direction
- see bug #5429822 UI should be mirrored for RTL locales (Arabic, Hebrew, farsi) Change-Id: Iea8a512311ee99548f39bbbe342f21eabaffbe09
-rw-r--r--core/java/android/app/ActionBar.java9
-rw-r--r--core/java/com/android/internal/widget/AbsActionBarView.java20
-rw-r--r--core/java/com/android/internal/widget/ActionBarContextView.java21
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java127
-rw-r--r--core/res/res/layout/action_bar_home.xml6
-rw-r--r--core/res/res/layout/action_bar_title_item.xml2
6 files changed, 119 insertions, 66 deletions
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index cff16ff..2337790 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -918,6 +918,8 @@ public abstract class ActionBar {
@ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"),
@ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"),
@ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"),
+ @ViewDebug.IntToString(from = Gravity.START, to = "START"),
+ @ViewDebug.IntToString(from = Gravity.END, to = "END"),
@ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"),
@ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"),
@ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
@@ -925,7 +927,7 @@ public abstract class ActionBar {
@ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
@ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
})
- public int gravity = -1;
+ public int gravity = Gravity.NO_GRAVITY;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
@@ -933,13 +935,14 @@ public abstract class ActionBar {
TypedArray a = c.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.ActionBar_LayoutParams);
gravity = a.getInt(
- com.android.internal.R.styleable.ActionBar_LayoutParams_layout_gravity, -1);
+ com.android.internal.R.styleable.ActionBar_LayoutParams_layout_gravity,
+ Gravity.NO_GRAVITY);
a.recycle();
}
public LayoutParams(int width, int height) {
super(width, height);
- this.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT;
+ this.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
}
public LayoutParams(int width, int height, int gravity) {
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 25a9c54..860a8d9 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -219,24 +219,22 @@ public abstract class AbsActionBarView extends ViewGroup {
return Math.max(0, availableWidth);
}
- protected int positionChild(View child, int x, int y, int contentHeight) {
- int childWidth = child.getMeasuredWidth();
- int childHeight = child.getMeasuredHeight();
- int childTop = y + (contentHeight - childHeight) / 2;
-
- child.layout(x, childTop, x + childWidth, childTop + childHeight);
-
- return childWidth;
+ static protected int next(int x, int val, boolean isRtl) {
+ return isRtl ? x - val : x + val;
}
- protected int positionChildInverse(View child, int x, int y, int contentHeight) {
+ protected int positionChild(View child, int x, int y, int contentHeight, boolean reverse) {
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
int childTop = y + (contentHeight - childHeight) / 2;
- child.layout(x - childWidth, childTop, x, childTop + childHeight);
+ if (reverse) {
+ child.layout(x - childWidth, childTop, x, childTop + childHeight);
+ } else {
+ child.layout(x, childTop, x + childWidth, childTop + childHeight);
+ }
- return childWidth;
+ return (reverse ? -childWidth : childWidth);
}
protected class VisibilityAnimListener implements Animator.AnimatorListener {
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 16f08f5..8bc1081 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -454,15 +454,18 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int x = getPaddingLeft();
+ final boolean isLayoutRtl = isLayoutRtl();
+ int x = isLayoutRtl ? r - l - getPaddingRight() : getPaddingLeft();
final int y = getPaddingTop();
final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
if (mClose != null && mClose.getVisibility() != GONE) {
MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams();
- x += lp.leftMargin;
- x += positionChild(mClose, x, y, contentHeight);
- x += lp.rightMargin;
+ final int startMargin = (isLayoutRtl ? lp.rightMargin : lp.leftMargin);
+ final int endMargin = (isLayoutRtl ? lp.leftMargin : lp.rightMargin);
+ x = next(x, startMargin, isLayoutRtl);
+ x += positionChild(mClose, x, y, contentHeight, isLayoutRtl);
+ x = next(x, endMargin, isLayoutRtl);
if (mAnimateInOnLayout) {
mAnimationMode = ANIMATE_IN;
@@ -473,17 +476,17 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
}
if (mTitleLayout != null && mCustomView == null && mTitleLayout.getVisibility() != GONE) {
- x += positionChild(mTitleLayout, x, y, contentHeight);
+ x += positionChild(mTitleLayout, x, y, contentHeight, isLayoutRtl);
}
if (mCustomView != null) {
- x += positionChild(mCustomView, x, y, contentHeight);
+ x += positionChild(mCustomView, x, y, contentHeight, isLayoutRtl);
}
-
- x = r - l - getPaddingRight();
+
+ x = isLayoutRtl ? getPaddingLeft() : r - l - getPaddingRight();
if (mMenuView != null) {
- x -= positionChildInverse(mMenuView, x, y, contentHeight);
+ x += positionChild(mMenuView, x, y, contentHeight, !isLayoutRtl);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 450f418..7da8d46 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -84,7 +84,7 @@ public class ActionBarView extends AbsActionBarView {
ActionBar.DISPLAY_SHOW_CUSTOM |
ActionBar.DISPLAY_SHOW_TITLE;
- private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL;
+ private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL;
private int mNavigationMode;
private int mDisplayOptions = -1;
@@ -872,7 +872,7 @@ public class ActionBarView extends AbsActionBarView {
}
homeLayout.measure(homeWidthSpec,
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
- final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset();
+ final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getStartOffset();
availableWidth = Math.max(0, availableWidth - homeWidth);
leftOfCenter = Math.max(0, availableWidth - homeWidth);
}
@@ -1010,8 +1010,6 @@ public class ActionBarView extends AbsActionBarView {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int x = getPaddingLeft();
- final int y = getPaddingTop();
final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
if (contentHeight <= 0) {
@@ -1019,13 +1017,23 @@ public class ActionBarView extends AbsActionBarView {
return;
}
+ final boolean isLayoutRtl = isLayoutRtl();
+ final int direction = isLayoutRtl ? +1 : -1;
+ int menuStart = isLayoutRtl ? getPaddingLeft() : r - l - getPaddingRight();
+ // In LTR mode, we start from left padding and go to the right; in RTL mode, we start
+ // from the padding right and go to the left (in reverse way)
+ int x = isLayoutRtl ? r - l - getPaddingRight() : getPaddingLeft();
+ final int y = getPaddingTop();
+
HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
boolean needsTouchDelegate = false;
int homeSlop = mMaxHomeSlop;
int homeRight = 0;
if (homeLayout.getVisibility() != GONE) {
- final int leftOffset = homeLayout.getLeftOffset();
- x += positionChild(homeLayout, x + leftOffset, y, contentHeight) + leftOffset;
+ final int startOffset = homeLayout.getStartOffset();
+ x += positionChild(homeLayout,
+ next(x, startOffset, isLayoutRtl), y, contentHeight, isLayoutRtl);
+ x = next(x, startOffset, isLayoutRtl);
needsTouchDelegate = homeLayout == mHomeLayout;
homeRight = x;
}
@@ -1034,7 +1042,7 @@ public class ActionBarView extends AbsActionBarView {
final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
(mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
if (showTitle) {
- x += positionChild(mTitleLayout, x, y, contentHeight);
+ x += positionChild(mTitleLayout, x, y, contentHeight, isLayoutRtl);
}
switch (mNavigationMode) {
@@ -1042,31 +1050,34 @@ public class ActionBarView extends AbsActionBarView {
break;
case ActionBar.NAVIGATION_MODE_LIST:
if (mListNavLayout != null) {
- if (showTitle) x += mItemPadding;
+ if (showTitle) {
+ x = next(x, mItemPadding, isLayoutRtl);
+ }
homeSlop = Math.min(homeSlop, Math.max(x - homeRight, 0));
- x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding;
+ x += positionChild(mListNavLayout, x, y, contentHeight, isLayoutRtl);
+ x = next(x, mItemPadding, isLayoutRtl);
}
break;
case ActionBar.NAVIGATION_MODE_TABS:
if (mTabScrollView != null) {
- if (showTitle) x += mItemPadding;
+ if (showTitle) x = next(x, mItemPadding, isLayoutRtl);
homeSlop = Math.min(homeSlop, Math.max(x - homeRight, 0));
- x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding;
+ x += positionChild(mTabScrollView, x, y, contentHeight, isLayoutRtl);
+ x = next(x, mItemPadding, isLayoutRtl);
}
break;
}
}
- int menuLeft = r - l - getPaddingRight();
if (mMenuView != null && mMenuView.getParent() == this) {
- positionChildInverse(mMenuView, menuLeft, y, contentHeight);
- menuLeft -= mMenuView.getMeasuredWidth();
+ positionChild(mMenuView, menuStart, y, contentHeight, !isLayoutRtl);
+ menuStart += direction * mMenuView.getMeasuredWidth();
}
if (mIndeterminateProgressView != null &&
mIndeterminateProgressView.getVisibility() != GONE) {
- positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight);
- menuLeft -= mIndeterminateProgressView.getMeasuredWidth();
+ positionChild(mIndeterminateProgressView, menuStart, y, contentHeight, !isLayoutRtl);
+ menuStart += direction * mIndeterminateProgressView.getMeasuredWidth();
}
View customView = null;
@@ -1077,51 +1088,64 @@ public class ActionBarView extends AbsActionBarView {
customView = mCustomNavView;
}
if (customView != null) {
+ final int resolvedLayoutDirection = getResolvedLayoutDirection();
ViewGroup.LayoutParams lp = customView.getLayoutParams();
+ lp.onResolveLayoutDirection(resolvedLayoutDirection);
final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
(ActionBar.LayoutParams) lp : null;
-
final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY;
final int navWidth = customView.getMeasuredWidth();
int topMargin = 0;
int bottomMargin = 0;
if (ablp != null) {
- x += ablp.leftMargin;
- menuLeft -= ablp.rightMargin;
+ x = next(x, ablp.getMarginStart(), isLayoutRtl);
+ menuStart += direction * ablp.getMarginEnd();
topMargin = ablp.topMargin;
bottomMargin = ablp.bottomMargin;
}
- int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+ int hgravity = gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
// See if we actually have room to truly center; if not push against left or right.
if (hgravity == Gravity.CENTER_HORIZONTAL) {
final int centeredLeft = ((mRight - mLeft) - navWidth) / 2;
- if (centeredLeft < x) {
- hgravity = Gravity.LEFT;
- } else if (centeredLeft + navWidth > menuLeft) {
- hgravity = Gravity.RIGHT;
+ if (isLayoutRtl) {
+ final int centeredStart = centeredLeft + navWidth;
+ final int centeredEnd = centeredLeft;
+ if (centeredStart > x) {
+ hgravity = Gravity.RIGHT;
+ } else if (centeredEnd < menuStart) {
+ hgravity = Gravity.LEFT;
+ }
+ } else {
+ final int centeredStart = centeredLeft;
+ final int centeredEnd = centeredLeft + navWidth;
+ if (centeredStart < x) {
+ hgravity = Gravity.LEFT;
+ } else if (centeredEnd > menuStart) {
+ hgravity = Gravity.RIGHT;
+ }
}
- } else if (gravity == -1) {
- hgravity = Gravity.LEFT;
+ } else if (gravity == Gravity.NO_GRAVITY) {
+ hgravity = Gravity.START;
}
int xpos = 0;
- switch (hgravity) {
+ switch (Gravity.getAbsoluteGravity(hgravity, resolvedLayoutDirection)) {
case Gravity.CENTER_HORIZONTAL:
xpos = ((mRight - mLeft) - navWidth) / 2;
break;
case Gravity.LEFT:
- xpos = x;
+ xpos = isLayoutRtl ? menuStart : x;
break;
case Gravity.RIGHT:
- xpos = menuLeft - navWidth;
+ xpos = isLayoutRtl ? x - navWidth : menuStart - navWidth;
break;
}
int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
- if (gravity == -1) {
+ if (gravity == Gravity.NO_GRAVITY) {
vgravity = Gravity.CENTER_VERTICAL;
}
@@ -1144,7 +1168,7 @@ public class ActionBarView extends AbsActionBarView {
customView.layout(xpos, ypos, xpos + customWidth,
ypos + customView.getMeasuredHeight());
homeSlop = Math.min(homeSlop, Math.max(xpos - homeRight, 0));
- x += customWidth;
+ x = next(x, customWidth, isLayoutRtl);
}
if (mProgressView != null) {
@@ -1290,7 +1314,7 @@ public class ActionBarView extends AbsActionBarView {
mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
}
- public int getLeftOffset() {
+ public int getStartOffset() {
return mUpView.getVisibility() == GONE ? mUpWidth : 0;
}
@@ -1340,25 +1364,50 @@ public class ActionBarView extends AbsActionBarView {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int vCenter = (b - t) / 2;
- int width = r - l;
+ final boolean isLayoutRtl = isLayoutRtl();
+ final int layoutDirection = getResolvedLayoutDirection();
+ final int width = getWidth();
int upOffset = 0;
if (mUpView.getVisibility() != GONE) {
final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
final int upHeight = mUpView.getMeasuredHeight();
final int upWidth = mUpView.getMeasuredWidth();
- final int upTop = vCenter - upHeight / 2;
- mUpView.layout(0, upTop, upWidth, upTop + upHeight);
upOffset = upLp.leftMargin + upWidth + upLp.rightMargin;
- width -= upOffset;
- l += upOffset;
+ final int upTop = vCenter - upHeight / 2;
+ final int upBottom = upTop + upHeight;
+ final int upRight;
+ final int upLeft;
+ if (isLayoutRtl) {
+ upRight = width;
+ upLeft = upRight - upWidth;
+ r -= upOffset;
+ } else {
+ upRight = upWidth;
+ upLeft = 0;
+ l += upOffset;
+ }
+ mUpView.layout(upLeft, upTop, upRight, upBottom);
}
+
final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
+ iconLp.onResolveLayoutDirection(layoutDirection);
final int iconHeight = mIconView.getMeasuredHeight();
final int iconWidth = mIconView.getMeasuredWidth();
final int hCenter = (r - l) / 2;
- final int iconLeft = upOffset + Math.max(iconLp.leftMargin, hCenter - iconWidth / 2);
final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2);
- mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight);
+ final int iconBottom = iconTop + iconHeight;
+ final int iconLeft;
+ final int iconRight;
+ int marginStart = iconLp.getMarginStart();
+ final int delta = Math.max(marginStart, hCenter - iconWidth / 2);
+ if (isLayoutRtl) {
+ iconRight = width - upOffset - delta;
+ iconLeft = iconRight - iconWidth;
+ } else {
+ iconLeft = upOffset + delta;
+ iconRight = iconLeft + iconWidth;
+ }
+ mIconView.layout(iconLeft, iconTop, iconRight, iconBottom);
}
}
diff --git a/core/res/res/layout/action_bar_home.xml b/core/res/res/layout/action_bar_home.xml
index 96467d0..91af7e9 100644
--- a/core/res/res/layout/action_bar_home.xml
+++ b/core/res/res/layout/action_bar_home.xml
@@ -21,15 +21,15 @@
android:background="?android:attr/actionBarItemBackground" >
<ImageView android:id="@android:id/up"
android:src="?android:attr/homeAsUpIndicator"
- android:layout_gravity="center_vertical|left"
+ android:layout_gravity="center_vertical|start"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="-8dip" />
+ android:layout_marginEnd="-8dip" />
<ImageView android:id="@android:id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="8dip"
+ android:layout_marginEnd="8dip"
android:layout_marginTop="@android:dimen/action_bar_icon_vertical_padding"
android:layout_marginBottom="@android:dimen/action_bar_icon_vertical_padding"
android:layout_gravity="center"
diff --git a/core/res/res/layout/action_bar_title_item.xml b/core/res/res/layout/action_bar_title_item.xml
index 2e21383..35c1264 100644
--- a/core/res/res/layout/action_bar_title_item.xml
+++ b/core/res/res/layout/action_bar_title_item.xml
@@ -31,7 +31,7 @@
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical|left"
+ android:layout_gravity="center_vertical|start"
android:orientation="vertical">
<TextView android:id="@+id/action_bar_title"
android:layout_width="wrap_content"