diff options
| author | Fabrice Di Meglio <fdimeglio@google.com> | 2013-03-26 15:50:24 -0700 |
|---|---|---|
| committer | Fabrice Di Meglio <fdimeglio@google.com> | 2013-03-26 17:27:33 -0700 |
| commit | 0072f64939b37a4d84940656c2180ad2e0594ff4 (patch) | |
| tree | c820fc3533f60b54f5d9087f250cf024b865fa6e /core/java/android/view/ViewGroup.java | |
| parent | 3bafc1a7056f93948219eea0d145ab61f05b30f4 (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.java | 115 |
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); } /** |
