Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f443f98e authored by Fabrice Di Meglio's avatar Fabrice Di Meglio
Browse files

Make RelativeLayout aware of layout direction

- see bug #5429822 UI should be mirrored for RTL locales (Arabic, Hebrew, farsi)

Change-Id: Ica92841fa0c13c25fcf89c4700b0771eec4fd6d7
parent 9a1aa4c4
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -607,12 +607,16 @@ package android {
    field public static final int layout_above = 16843140; // 0x1010184
    field public static final int layout_alignBaseline = 16843142; // 0x1010186
    field public static final int layout_alignBottom = 16843146; // 0x101018a
    field public static final int layout_alignEnd = 16843706; // 0x10103ba
    field public static final int layout_alignLeft = 16843143; // 0x1010187
    field public static final int layout_alignParentBottom = 16843150; // 0x101018e
    field public static final int layout_alignParentEnd = 16843708; // 0x10103bc
    field public static final int layout_alignParentLeft = 16843147; // 0x101018b
    field public static final int layout_alignParentRight = 16843149; // 0x101018d
    field public static final int layout_alignParentStart = 16843707; // 0x10103bb
    field public static final int layout_alignParentTop = 16843148; // 0x101018c
    field public static final int layout_alignRight = 16843145; // 0x1010189
    field public static final int layout_alignStart = 16843705; // 0x10103b9
    field public static final int layout_alignTop = 16843144; // 0x1010188
    field public static final int layout_alignWithParentIfMissing = 16843154; // 0x1010192
    field public static final int layout_below = 16843141; // 0x1010185
@@ -634,8 +638,10 @@ package android {
    field public static final int layout_rowSpan = 16843644; // 0x101037c
    field public static final int layout_scale = 16843155; // 0x1010193
    field public static final int layout_span = 16843085; // 0x101014d
    field public static final int layout_toEndOf = 16843704; // 0x10103b8
    field public static final int layout_toLeftOf = 16843138; // 0x1010182
    field public static final int layout_toRightOf = 16843139; // 0x1010183
    field public static final int layout_toStartOf = 16843703; // 0x10103b7
    field public static final int layout_weight = 16843137; // 0x1010181
    field public static final int layout_width = 16842996; // 0x10100f4
    field public static final int layout_x = 16843135; // 0x101017f
@@ -24901,9 +24907,12 @@ package android.view {
    ctor public ViewGroup.MarginLayoutParams(int, int);
    ctor public ViewGroup.MarginLayoutParams(android.view.ViewGroup.MarginLayoutParams);
    ctor public ViewGroup.MarginLayoutParams(android.view.ViewGroup.LayoutParams);
    method public int getLayoutDirection();
    method public int getMarginEnd();
    method public int getMarginStart();
    method protected boolean isLayoutRtl();
    method public boolean isMarginRelative();
    method public void setLayoutDirection(int);
    method public void setMargins(int, int, int, int);
    field public int bottomMargin;
    field public int endMargin;
@@ -28198,19 +28207,25 @@ package android.widget {
    field public static final int ABOVE = 2; // 0x2
    field public static final int ALIGN_BASELINE = 4; // 0x4
    field public static final int ALIGN_BOTTOM = 8; // 0x8
    field public static final int ALIGN_END = 19; // 0x13
    field public static final int ALIGN_LEFT = 5; // 0x5
    field public static final int ALIGN_PARENT_BOTTOM = 12; // 0xc
    field public static final int ALIGN_PARENT_END = 21; // 0x15
    field public static final int ALIGN_PARENT_LEFT = 9; // 0x9
    field public static final int ALIGN_PARENT_RIGHT = 11; // 0xb
    field public static final int ALIGN_PARENT_START = 20; // 0x14
    field public static final int ALIGN_PARENT_TOP = 10; // 0xa
    field public static final int ALIGN_RIGHT = 7; // 0x7
    field public static final int ALIGN_START = 18; // 0x12
    field public static final int ALIGN_TOP = 6; // 0x6
    field public static final int BELOW = 3; // 0x3
    field public static final int CENTER_HORIZONTAL = 14; // 0xe
    field public static final int CENTER_IN_PARENT = 13; // 0xd
    field public static final int CENTER_VERTICAL = 15; // 0xf
    field public static final int END_OF = 17; // 0x11
    field public static final int LEFT_OF = 0; // 0x0
    field public static final int RIGHT_OF = 1; // 0x1
    field public static final int START_OF = 16; // 0x10
    field public static final int TRUE = -1; // 0xffffffff
  }
+35 −8
Original line number Diff line number Diff line
@@ -5504,13 +5504,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager

        /**
         * The default start and end margin.
         * @hide
         */
        static private final int DEFAULT_RELATIVE = Integer.MIN_VALUE;
        public static final int DEFAULT_RELATIVE = Integer.MIN_VALUE;

        private int initialLeftMargin;
        private int initialRightMargin;

        private int layoutDirection;
        private static int LAYOUT_DIRECTION_UNDEFINED = -1;

        // Layout direction undefined by default
        private int layoutDirection = LAYOUT_DIRECTION_UNDEFINED;

        /**
         * Creates a new set of layout parameters. The values are extracted from
@@ -5553,9 +5557,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            initialLeftMargin = leftMargin;
            initialRightMargin = rightMargin;

            // LTR by default
            layoutDirection = View.LAYOUT_DIRECTION_LTR;

            a.recycle();
        }

@@ -5585,7 +5586,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            this.initialLeftMargin = source.leftMargin;
            this.initialRightMargin = source.rightMargin;

            this.layoutDirection = source.layoutDirection;
            setLayoutDirection(source.layoutDirection);
        }

        /**
@@ -5688,19 +5689,41 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
         *
         * @return true if either marginStart or marginEnd has been set
         * @return true if either marginStart or marginEnd has been set.
         */
        public boolean isMarginRelative() {
            return (startMargin != DEFAULT_RELATIVE) || (endMargin != DEFAULT_RELATIVE);
        }

        /**
         * Set the layout direction
         * @param layoutDirection the layout direction.
         *        Should be either {@link View#LAYOUT_DIRECTION_LTR}
         *                     or {@link View#LAYOUT_DIRECTION_RTL}.
         */
        public void setLayoutDirection(int layoutDirection) {
            if (layoutDirection != View.LAYOUT_DIRECTION_LTR &&
                    layoutDirection != View.LAYOUT_DIRECTION_RTL) return;
            this.layoutDirection = layoutDirection;
        }

        /**
         * Retuns the layout direction. Can be either {@link View#LAYOUT_DIRECTION_LTR} or
         * {@link View#LAYOUT_DIRECTION_RTL}.
         *
         * @return the layout direction.
         */
        public int getLayoutDirection() {
            return layoutDirection;
        }

        /**
         * This will be called by {@link android.view.View#requestLayout()}. Left and Right margins
         * may be overridden depending on layout direction.
         */
        @Override
        public void onResolveLayoutDirection(int layoutDirection) {
            this.layoutDirection = layoutDirection;
            setLayoutDirection(layoutDirection);

            if (!isMarginRelative()) return;

@@ -5717,6 +5740,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            }
        }

        protected boolean isLayoutRtl() {
            return (layoutDirection == View.LAYOUT_DIRECTION_RTL);
        }

        /**
         * @hide
         */
+183 −22
Original line number Diff line number Diff line
@@ -149,8 +149,34 @@ public class RelativeLayout extends ViewGroup {
     * bounds of its RelativeLayout parent.
     */
    public static final int CENTER_VERTICAL          = 15;
    /**
     * Rule that aligns a child's end edge with another child's start edge.
     */
    public static final int START_OF                 = 16;
    /**
     * Rule that aligns a child's start edge with another child's end edge.
     */
    public static final int END_OF                   = 17;
    /**
     * Rule that aligns a child's start edge with another child's start edge.
     */
    public static final int ALIGN_START              = 18;
    /**
     * Rule that aligns a child's end edge with another child's end edge.
     */
    public static final int ALIGN_END                = 19;
    /**
     * Rule that aligns the child's start edge with its RelativeLayout
     * parent's start edge.
     */
    public static final int ALIGN_PARENT_START       = 20;
    /**
     * Rule that aligns the child's end edge with its RelativeLayout
     * parent's end edge.
     */
    public static final int ALIGN_PARENT_END         = 21;

    private static final int VERB_COUNT              = 16;
    private static final int VERB_COUNT              = 22;


    private static final int[] RULES_VERTICAL = {
@@ -158,13 +184,13 @@ public class RelativeLayout extends ViewGroup {
    };

    private static final int[] RULES_HORIZONTAL = {
            LEFT_OF, RIGHT_OF, ALIGN_LEFT, ALIGN_RIGHT
            LEFT_OF, RIGHT_OF, ALIGN_LEFT, ALIGN_RIGHT, START_OF, END_OF, ALIGN_START, ALIGN_END
    };

    private View mBaselineView = null;
    private boolean mHasBaselineAlignedChild;

    private int mGravity = Gravity.LEFT | Gravity.TOP;
    private int mGravity = Gravity.START | Gravity.TOP;
    private final Rect mContentBounds = new Rect();
    private final Rect mSelfBounds = new Rect();
    private int mIgnoreGravity;
@@ -204,7 +230,7 @@ public class RelativeLayout extends ViewGroup {

    /**
     * Defines which View is ignored when the gravity is applied. This setting has no
     * effect if the gravity is <code>Gravity.LEFT | Gravity.TOP</code>.
     * effect if the gravity is <code>Gravity.START | Gravity.TOP</code>.
     *
     * @param viewId The id of the View to be ignored by gravity, or 0 if no View
     *        should be ignored.
@@ -234,7 +260,7 @@ public class RelativeLayout extends ViewGroup {

    /**
     * Describes how the child views are positioned. Defaults to
     * <code>Gravity.LEFT | Gravity.TOP</code>.
     * <code>Gravity.START | Gravity.TOP</code>.
     *
     * <p>Note that since RelativeLayout considers the positioning of each child
     * relative to one another to be significant, setting gravity will affect
@@ -369,7 +395,7 @@ public class RelativeLayout extends ViewGroup {

        View ignore = null;
        int gravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
        final boolean horizontalGravity = gravity != Gravity.LEFT && gravity != 0;
        final boolean horizontalGravity = gravity != Gravity.START && gravity != 0;
        gravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
        final boolean verticalGravity = gravity != Gravity.TOP && gravity != 0;

@@ -457,6 +483,8 @@ public class RelativeLayout extends ViewGroup {
            }
        }

        final int layoutDirection = getResolvedLayoutDirection();

        if (isWrapContentWidth) {
            // Width already has left padding in it since it was calculated by looking at
            // the right of each child view
@@ -474,7 +502,7 @@ public class RelativeLayout extends ViewGroup {
                    View child = getChildAt(i);
                    if (child.getVisibility() != GONE) {
                        LayoutParams params = (LayoutParams) child.getLayoutParams();
                        final int[] rules = params.getRules();
                        final int[] rules = params.getRules(layoutDirection);
                        if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) {
                            centerHorizontal(child, params, width);
                        } else if (rules[ALIGN_PARENT_RIGHT] != 0) {
@@ -504,7 +532,7 @@ public class RelativeLayout extends ViewGroup {
                    View child = getChildAt(i);
                    if (child.getVisibility() != GONE) {
                        LayoutParams params = (LayoutParams) child.getLayoutParams();
                        final int[] rules = params.getRules();
                        final int[] rules = params.getRules(layoutDirection);
                        if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) {
                            centerVertical(child, params, height);
                        } else if (rules[ALIGN_PARENT_BOTTOM] != 0) {
@@ -523,7 +551,6 @@ public class RelativeLayout extends ViewGroup {
                    height - mPaddingBottom);

            final Rect contentBounds = mContentBounds;
            final int layoutDirection = getResolvedLayoutDirection();
            Gravity.apply(mGravity, right - left, bottom - top, selfBounds, contentBounds,
                    layoutDirection);

@@ -551,7 +578,8 @@ public class RelativeLayout extends ViewGroup {
    }

    private void alignBaseline(View child, LayoutParams params) {
        int[] rules = params.getRules();
        final int layoutDirection = getResolvedLayoutDirection();
        int[] rules = params.getRules(layoutDirection);
        int anchorBaseline = getRelatedViewBaseline(rules, ALIGN_BASELINE);

        if (anchorBaseline != -1) {
@@ -619,7 +647,7 @@ public class RelativeLayout extends ViewGroup {

    /**
     * Get a measure spec that accounts for all of the constraints on this view.
     * This includes size contstraints imposed by the RelativeLayout as well as
     * This includes size constraints imposed by the RelativeLayout as well as
     * the View's desired dimension.
     *
     * @param childStart The left or top field of the child's layout params
@@ -672,7 +700,7 @@ public class RelativeLayout extends ViewGroup {
                    childSpecSize = childSize;
                }
            } else if (childSize == LayoutParams.MATCH_PARENT) {
                // Child wanted to be as big as possible. Give all availble
                // Child wanted to be as big as possible. Give all available
                // space
                childSpecMode = MeasureSpec.EXACTLY;
                childSpecSize = maxAvailable;
@@ -681,7 +709,7 @@ public class RelativeLayout extends ViewGroup {
                // to communicate available space if we know
                // our max size
                if (maxAvailable >= 0) {
                    // We have a maxmum size in this dimension.
                    // We have a maximum size in this dimension.
                    childSpecMode = MeasureSpec.AT_MOST;
                    childSpecSize = maxAvailable;
                } else {
@@ -699,7 +727,9 @@ public class RelativeLayout extends ViewGroup {
    private boolean positionChildHorizontal(View child, LayoutParams params, int myWidth,
            boolean wrapContent) {

        int[] rules = params.getRules();
        final int layoutDirection = getResolvedLayoutDirection();
        int[] rules = params.getRules(layoutDirection);
        params.onResolveLayoutDirection(layoutDirection);

        if (params.mLeft < 0 && params.mRight >= 0) {
            // Right is fixed, but left varies
@@ -717,12 +747,19 @@ public class RelativeLayout extends ViewGroup {
                    params.mRight = params.mLeft + child.getMeasuredWidth();
                }
                return true;
            } else {
                // This is the default case. For RTL we start from the right and for LTR we start
                // from the left. This will give LEFT/TOP for LTR and RIGHT/TOP for RTL.
                if (isLayoutRtl()) {
                    params.mRight = myWidth - mPaddingRight- params.rightMargin;
                    params.mLeft = params.mRight - child.getMeasuredWidth();
                } else {
                    params.mLeft = mPaddingLeft + params.leftMargin;
                    params.mRight = params.mLeft + child.getMeasuredWidth();
                }
            }
        return rules[ALIGN_PARENT_RIGHT] != 0;
        }
        return rules[ALIGN_PARENT_END] != 0;
    }

    private boolean positionChildVertical(View child, LayoutParams params, int myHeight,
@@ -755,7 +792,8 @@ public class RelativeLayout extends ViewGroup {
    }

    private void applyHorizontalSizeRules(LayoutParams childParams, int myWidth) {
        int[] rules = childParams.getRules();
        final int layoutDirection = getResolvedLayoutDirection();
        int[] rules = childParams.getRules(layoutDirection);
        RelativeLayout.LayoutParams anchorParams;

        // -1 indicated a "soft requirement" in that direction. For example:
@@ -945,8 +983,8 @@ public class RelativeLayout extends ViewGroup {
            if (child.getVisibility() != GONE) {
                RelativeLayout.LayoutParams st =
                        (RelativeLayout.LayoutParams) child.getLayoutParams();
                st.onResolveLayoutDirection(getResolvedLayoutDirection());
                child.layout(st.mLeft, st.mTop, st.mRight, st.mBottom);

            }
        }
    }
@@ -1061,6 +1099,12 @@ public class RelativeLayout extends ViewGroup {
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_centerInParent
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_centerHorizontal
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_centerVertical
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_toStartOf
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_toEndOf
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_alignStart
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_alignEnd
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_alignParentStart
     * @attr ref android.R.styleable#RelativeLayout_Layout_layout_alignParentEnd
     */
    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
        @ViewDebug.ExportedProperty(category = "layout", resolveId = true, indexMapping = {
@@ -1079,15 +1123,28 @@ public class RelativeLayout extends ViewGroup {
            @ViewDebug.IntToString(from = CENTER_IN_PARENT,    to = "center"),
            @ViewDebug.IntToString(from = CENTER_VERTICAL,     to = "centerVertical"),
            @ViewDebug.IntToString(from = LEFT_OF,             to = "leftOf"),
            @ViewDebug.IntToString(from = RIGHT_OF,            to = "rightOf")
            @ViewDebug.IntToString(from = RIGHT_OF,            to = "rightOf"),
            @ViewDebug.IntToString(from = ALIGN_START,         to = "alignStart"),
            @ViewDebug.IntToString(from = ALIGN_END,           to = "alignEnd"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_START,  to = "alignParentStart"),
            @ViewDebug.IntToString(from = ALIGN_PARENT_END,    to = "alignParentEnd"),
            @ViewDebug.IntToString(from = START_OF,            to = "startOf"),
            @ViewDebug.IntToString(from = END_OF,              to = "endOf")
        }, mapping = {
            @ViewDebug.IntToString(from = TRUE, to = "true"),
            @ViewDebug.IntToString(from = 0,    to = "false/NO_ID")
        })

        private int[] mRules = new int[VERB_COUNT];
        private int[] mInitialRules = new int[VERB_COUNT];

        private int mLeft, mTop, mRight, mBottom;

        private int mStart = DEFAULT_RELATIVE;
        private int mEnd = DEFAULT_RELATIVE;

        private boolean mRulesChanged = false;

        /**
         * When true, uses the parent as the anchor if the anchor doesn't exist or if
         * the anchor's visibility is GONE.
@@ -1102,6 +1159,7 @@ public class RelativeLayout extends ViewGroup {
                    com.android.internal.R.styleable.RelativeLayout_Layout);

            final int[] rules = mRules;
            final int[] initialRules = mInitialRules;

            final int N = a.getIndexCount();
            for (int i = 0; i < N; i++) {
@@ -1158,7 +1216,29 @@ public class RelativeLayout extends ViewGroup {
                    case com.android.internal.R.styleable.RelativeLayout_Layout_layout_centerVertical:
                        rules[CENTER_VERTICAL] = a.getBoolean(attr, false) ? TRUE : 0;
                       break;
                    case com.android.internal.R.styleable.RelativeLayout_Layout_layout_toStartOf:
                        rules[START_OF] = a.getResourceId(attr, 0);
                        break;
                    case com.android.internal.R.styleable.RelativeLayout_Layout_layout_toEndOf:
                        rules[END_OF] = a.getResourceId(attr, 0);
                        break;
                    case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignStart:
                        rules[ALIGN_START] = a.getResourceId(attr, 0);
                        break;
                    case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignEnd:
                        rules[ALIGN_END] = a.getResourceId(attr, 0);
                        break;
                    case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentStart:
                        rules[ALIGN_PARENT_START] = a.getBoolean(attr, false) ? TRUE : 0;
                        break;
                    case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentEnd:
                        rules[ALIGN_PARENT_END] = a.getBoolean(attr, false) ? TRUE : 0;
                        break;
                }
            }

            for (int n = LEFT_OF; n < VERB_COUNT; n++) {
                initialRules[n] = rules[n];
            }

            a.recycle();
@@ -1192,7 +1272,7 @@ public class RelativeLayout extends ViewGroup {
         * Adds a layout rule to be interpreted by the RelativeLayout. This
         * method should only be used for constraints that don't refer to another sibling
         * (e.g., CENTER_IN_PARENT) or take a boolean value ({@link RelativeLayout#TRUE}
         * for true or - for false). To specify a verb that takes a subject, use
         * for true or 0 for false). To specify a verb that takes a subject, use
         * {@link #addRule(int, int)} instead.
         *
         * @param verb One of the verbs defined by
@@ -1202,6 +1282,8 @@ public class RelativeLayout extends ViewGroup {
         */
        public void addRule(int verb) {
            mRules[verb] = TRUE;
            mInitialRules[verb] = TRUE;
            mRulesChanged = true;
        }

        /**
@@ -1220,12 +1302,73 @@ public class RelativeLayout extends ViewGroup {
         */
        public void addRule(int verb, int anchor) {
            mRules[verb] = anchor;
            mInitialRules[verb] = anchor;
            mRulesChanged = true;
        }

        private boolean hasRelativeRules() {
            return (mInitialRules[START_OF] != 0 || mInitialRules[END_OF] != 0 ||
                    mInitialRules[ALIGN_START] != 0 || mInitialRules[ALIGN_END] != 0 ||
                    mInitialRules[ALIGN_PARENT_START] != 0 || mInitialRules[ALIGN_PARENT_END] != 0);
        }

        private void resolveRules(int layoutDirection) {
            final boolean isLayoutRtl = (layoutDirection == View.LAYOUT_DIRECTION_RTL);
            // Reset to initial state
            for (int n = LEFT_OF; n < VERB_COUNT; n++) {
                mRules[n] = mInitialRules[n];
            }
            // Apply rules depending on direction
            if (mRules[ALIGN_START] != 0) {
                mRules[isLayoutRtl ? ALIGN_RIGHT : ALIGN_LEFT] = mRules[ALIGN_START];
            }
            if (mRules[ALIGN_END] != 0) {
                mRules[isLayoutRtl ? ALIGN_LEFT : ALIGN_RIGHT] = mRules[ALIGN_END];
            }
            if (mRules[START_OF] != 0) {
                mRules[isLayoutRtl ? RIGHT_OF : LEFT_OF] = mRules[START_OF];
            }
            if (mRules[END_OF] != 0) {
                mRules[isLayoutRtl ? LEFT_OF : RIGHT_OF] = mRules[END_OF];
            }
            if (mRules[ALIGN_PARENT_START] != 0) {
                mRules[isLayoutRtl ? ALIGN_PARENT_RIGHT : ALIGN_PARENT_LEFT] = mRules[ALIGN_PARENT_START];
            }
            if (mRules[ALIGN_PARENT_END] != 0) {
                mRules[isLayoutRtl ? ALIGN_PARENT_LEFT : ALIGN_PARENT_RIGHT] = mRules[ALIGN_PARENT_END];
            }
            mRulesChanged = false;
        }

        /**
         * Retrieves a complete list of all supported rules, where the index is the rule
         * verb, and the element value is the value specified, or "false" if it was never
         * set. If there are relative rules defined (*_START / *_END), they will be resolved
         * depending on the layout direction.
         *
         * @param layoutDirection the direction of the layout.
         *                        Should be either {@link View#LAYOUT_DIRECTION_LTR}
         *                        or {@link View#LAYOUT_DIRECTION_RTL}
         * @return the supported rules
         * @see #addRule(int, int)
         *
         * @hide
         */
        public int[] getRules(int layoutDirection) {
            if (hasRelativeRules() &&
                    (mRulesChanged || layoutDirection != getLayoutDirection())) {
                resolveRules(layoutDirection);
                if (layoutDirection != getLayoutDirection()) {
                    setLayoutDirection(layoutDirection);
                }
            }
            return mRules;
        }

        /**
         * Retrieves a complete list of all supported rules, where the index is the rule
         * verb, and the element value is the value specified, or "false" if it was never
         * set.
         * set. There will be no resolution of relative rules done.
         *
         * @return the supported rules
         * @see #addRule(int, int)
@@ -1233,6 +1376,24 @@ public class RelativeLayout extends ViewGroup {
        public int[] getRules() {
            return mRules;
        }

        @Override
        public void onResolveLayoutDirection(int layoutDirection) {
            final boolean isLayoutRtl = isLayoutRtl();
            if (isLayoutRtl) {
                if (mStart != DEFAULT_RELATIVE) mRight = mStart;
                if (mEnd != DEFAULT_RELATIVE) mLeft = mEnd;
            } else {
                if (mStart != DEFAULT_RELATIVE) mLeft = mStart;
                if (mEnd != DEFAULT_RELATIVE) mRight = mEnd;
            }

            if (hasRelativeRules() && layoutDirection != getLayoutDirection()) {
                resolveRules(layoutDirection);
            }
            // This will set the layout direction
            super.onResolveLayoutDirection(layoutDirection);
        }
    }

    private static class DependencyGraph {
+18 −0

File changed.

Preview size limit exceeded, changes collapsed.

+6 −0
Original line number Diff line number Diff line
@@ -3670,5 +3670,11 @@
  <public type="attr" name="paddingEnd"/>
  <public type="attr" name="layout_marginStart"/>
  <public type="attr" name="layout_marginEnd"/>
  <public type="attr" name="layout_toStartOf" />
  <public type="attr" name="layout_toEndOf" />
  <public type="attr" name="layout_alignStart" />
  <public type="attr" name="layout_alignEnd" />
  <public type="attr" name="layout_alignParentStart" />
  <public type="attr" name="layout_alignParentEnd" />

</resources>