summaryrefslogtreecommitdiff
path: root/core/java/android/view/ViewGroup.java
diff options
context:
space:
mode:
authorFabrice Di Meglio <fdimeglio@google.com>2013-03-26 15:50:24 -0700
committerFabrice Di Meglio <fdimeglio@google.com>2013-03-26 17:27:33 -0700
commit0072f64939b37a4d84940656c2180ad2e0594ff4 (patch)
treec820fc3533f60b54f5d9087f250cf024b865fa6e /core/java/android/view/ViewGroup.java
parent3bafc1a7056f93948219eea0d145ab61f05b30f4 (diff)
Fix bug #8480245 ViewGroup layout margins can be wrong in RTL mode
- fix resolution of MarginLayoutParams - update related RelativeLayout code Change-Id: I261f127a8897f60d316fed2a73e6e76020e542cc
Diffstat (limited to 'core/java/android/view/ViewGroup.java')
-rw-r--r--core/java/android/view/ViewGroup.java115
1 files changed, 78 insertions, 37 deletions
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d63f7bc8de89..77233bb2960f 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -51,6 +51,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
+import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
+
/**
* <p>
* A <code>ViewGroup</code> is a special view that can contain other views
@@ -5861,7 +5863,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
- private int startMargin = DEFAULT_RELATIVE;
+ private int startMargin = DEFAULT_MARGIN_RELATIVE;
/**
* The end margin in pixels of the child.
@@ -5869,21 +5871,21 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
- private int endMargin = DEFAULT_RELATIVE;
+ private int endMargin = DEFAULT_MARGIN_RELATIVE;
/**
* The default start and end margin.
* @hide
*/
- public static final int DEFAULT_RELATIVE = Integer.MIN_VALUE;
+ public static final int DEFAULT_MARGIN_RELATIVE = Integer.MIN_VALUE;
- private int initialLeftMargin;
- private int initialRightMargin;
+ // Layout direction is LTR by default
+ private int mLayoutDirection = LAYOUT_DIRECTION_LTR;
- private static int LAYOUT_DIRECTION_UNDEFINED = -1;
+ private static int DEFAULT_MARGIN_RESOLVED = 0;
- // Layout direction undefined by default
- private int layoutDirection = LAYOUT_DIRECTION_UNDEFINED;
+ private boolean mNeedResolution = false;
+ private boolean mIsRtlCompatibilityMode = true;
/**
* Creates a new set of layout parameters. The values are extracted from
@@ -5910,21 +5912,30 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
bottomMargin = margin;
} else {
leftMargin = a.getDimensionPixelSize(
- R.styleable.ViewGroup_MarginLayout_layout_marginLeft, 0);
+ R.styleable.ViewGroup_MarginLayout_layout_marginLeft,
+ DEFAULT_MARGIN_RESOLVED);
topMargin = a.getDimensionPixelSize(
- R.styleable.ViewGroup_MarginLayout_layout_marginTop, 0);
+ R.styleable.ViewGroup_MarginLayout_layout_marginTop,
+ DEFAULT_MARGIN_RESOLVED);
rightMargin = a.getDimensionPixelSize(
- R.styleable.ViewGroup_MarginLayout_layout_marginRight, 0);
+ R.styleable.ViewGroup_MarginLayout_layout_marginRight,
+ DEFAULT_MARGIN_RESOLVED);
bottomMargin = a.getDimensionPixelSize(
- R.styleable.ViewGroup_MarginLayout_layout_marginBottom, 0);
+ R.styleable.ViewGroup_MarginLayout_layout_marginBottom,
+ DEFAULT_MARGIN_RESOLVED);
startMargin = a.getDimensionPixelSize(
- R.styleable.ViewGroup_MarginLayout_layout_marginStart, DEFAULT_RELATIVE);
+ R.styleable.ViewGroup_MarginLayout_layout_marginStart,
+ DEFAULT_MARGIN_RELATIVE);
endMargin = a.getDimensionPixelSize(
- R.styleable.ViewGroup_MarginLayout_layout_marginEnd, DEFAULT_RELATIVE);
+ R.styleable.ViewGroup_MarginLayout_layout_marginEnd,
+ DEFAULT_MARGIN_RELATIVE);
+
+ mNeedResolution = isMarginRelative();
}
- initialLeftMargin = leftMargin;
- initialRightMargin = rightMargin;
+ final boolean hasRtlSupport = c.getApplicationInfo().hasRtlSupport();
+ final int targetSdkVersion = c.getApplicationInfo().targetSdkVersion;
+ mIsRtlCompatibilityMode = targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport;
a.recycle();
}
@@ -5934,6 +5945,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
public MarginLayoutParams(int width, int height) {
super(width, height);
+
+ mNeedResolution = false;
+ mIsRtlCompatibilityMode = false;
}
/**
@@ -5952,10 +5966,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
this.startMargin = source.startMargin;
this.endMargin = source.endMargin;
- this.initialLeftMargin = source.leftMargin;
- this.initialRightMargin = source.rightMargin;
+ this.mNeedResolution = source.mNeedResolution;
+ this.mIsRtlCompatibilityMode = source.mIsRtlCompatibilityMode;
- setLayoutDirection(source.layoutDirection);
+ setLayoutDirection(source.mLayoutDirection);
}
/**
@@ -5963,6 +5977,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
public MarginLayoutParams(LayoutParams source) {
super(source);
+
+ mNeedResolution = false;
+ mIsRtlCompatibilityMode = false;
}
/**
@@ -5985,8 +6002,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
topMargin = top;
rightMargin = right;
bottomMargin = bottom;
- initialLeftMargin = left;
- initialRightMargin = right;
+ mNeedResolution = isMarginRelative();
}
/**
@@ -6012,8 +6028,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
topMargin = top;
endMargin = end;
bottomMargin = bottom;
- initialLeftMargin = 0;
- initialRightMargin = 0;
+ mNeedResolution = true;
}
/**
@@ -6025,6 +6040,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
public void setMarginStart(int start) {
startMargin = start;
+ mNeedResolution = true;
}
/**
@@ -6035,8 +6051,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @return the start margin in pixels.
*/
public int getMarginStart() {
- if (startMargin != DEFAULT_RELATIVE) return startMargin;
- switch(layoutDirection) {
+ if (startMargin != DEFAULT_MARGIN_RELATIVE) return startMargin;
+ if (mNeedResolution) {
+ doResolveMargins();
+ }
+ switch(mLayoutDirection) {
case View.LAYOUT_DIRECTION_RTL:
return rightMargin;
case View.LAYOUT_DIRECTION_LTR:
@@ -6054,6 +6073,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
public void setMarginEnd(int end) {
endMargin = end;
+ mNeedResolution = true;
}
/**
@@ -6064,8 +6084,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @return the end margin in pixels.
*/
public int getMarginEnd() {
- if (endMargin != DEFAULT_RELATIVE) return endMargin;
- switch(layoutDirection) {
+ if (endMargin != DEFAULT_MARGIN_RELATIVE) return endMargin;
+ if (mNeedResolution) {
+ doResolveMargins();
+ }
+ switch(mLayoutDirection) {
case View.LAYOUT_DIRECTION_RTL:
return leftMargin;
case View.LAYOUT_DIRECTION_LTR:
@@ -6083,7 +6106,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @return true if either marginStart or marginEnd has been set.
*/
public boolean isMarginRelative() {
- return (startMargin != DEFAULT_RELATIVE) || (endMargin != DEFAULT_RELATIVE);
+ return (startMargin != DEFAULT_MARGIN_RELATIVE || endMargin != DEFAULT_MARGIN_RELATIVE);
}
/**
@@ -6095,7 +6118,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public void setLayoutDirection(int layoutDirection) {
if (layoutDirection != View.LAYOUT_DIRECTION_LTR &&
layoutDirection != View.LAYOUT_DIRECTION_RTL) return;
- this.layoutDirection = layoutDirection;
+ if (layoutDirection != this.mLayoutDirection) {
+ this.mLayoutDirection = layoutDirection;
+ this.mNeedResolution = isMarginRelative();
+ }
}
/**
@@ -6105,7 +6131,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @return the layout direction.
*/
public int getLayoutDirection() {
- return layoutDirection;
+ return mLayoutDirection;
}
/**
@@ -6116,26 +6142,41 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public void resolveLayoutDirection(int layoutDirection) {
setLayoutDirection(layoutDirection);
- if (!isMarginRelative()) return;
+ // No relative margin or pre JB-MR1 case or no need to resolve, just dont do anything
+ // Will use the left and right margins if no relative margin is defined.
+ if (!isMarginRelative() || !mNeedResolution || mIsRtlCompatibilityMode) return;
+
+ // Proceed with resolution
+ doResolveMargins();
+ }
- switch(layoutDirection) {
+ private void doResolveMargins() {
+ // We have some relative margins (either the start one or the end one or both). So use
+ // them and override what has been defined for left and right margins. If either start
+ // or end margin is not defined, just set it to default "0".
+ switch(mLayoutDirection) {
case View.LAYOUT_DIRECTION_RTL:
- leftMargin = (endMargin > DEFAULT_RELATIVE) ? endMargin : initialLeftMargin;
- rightMargin = (startMargin > DEFAULT_RELATIVE) ? startMargin : initialRightMargin;
+ leftMargin = (endMargin > DEFAULT_MARGIN_RELATIVE) ?
+ endMargin : DEFAULT_MARGIN_RESOLVED;
+ rightMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ?
+ startMargin : DEFAULT_MARGIN_RESOLVED;
break;
case View.LAYOUT_DIRECTION_LTR:
default:
- leftMargin = (startMargin > DEFAULT_RELATIVE) ? startMargin : initialLeftMargin;
- rightMargin = (endMargin > DEFAULT_RELATIVE) ? endMargin : initialRightMargin;
+ leftMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ?
+ startMargin : DEFAULT_MARGIN_RESOLVED;
+ rightMargin = (endMargin > DEFAULT_MARGIN_RELATIVE) ?
+ endMargin : DEFAULT_MARGIN_RESOLVED;
break;
}
+ mNeedResolution = false;
}
/**
* @hide
*/
public boolean isLayoutRtl() {
- return (layoutDirection == View.LAYOUT_DIRECTION_RTL);
+ return (mLayoutDirection == View.LAYOUT_DIRECTION_RTL);
}
/**