summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt15
-rw-r--r--core/java/android/view/ViewGroup.java43
-rw-r--r--core/java/android/widget/RelativeLayout.java205
-rwxr-xr-xcore/res/res/values/attrs.xml18
-rw-r--r--core/res/res/values/public.xml6
5 files changed, 257 insertions, 30 deletions
diff --git a/api/current.txt b/api/current.txt
index 31bb0b8..a4fc829 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -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
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 4e6e2ce..147669f 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -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
*/
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 29cf000..d9bde10 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -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
@@ -718,11 +748,18 @@ public class RelativeLayout extends ViewGroup {
}
return true;
} else {
- params.mLeft = mPaddingLeft + params.leftMargin;
- params.mRight = params.mLeft + child.getMeasuredWidth();
+ // 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,9 +1216,31 @@ 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 {
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 0477eca..258914b 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3634,6 +3634,24 @@
<!-- If set to true, the parent will be used as the anchor when the anchor cannot be
be found for layout_toLeftOf, layout_toRightOf, etc. -->
<attr name="layout_alignWithParentIfMissing" format="boolean" />
+ <!-- Positions the end edge of this view to the start of the given anchor view ID.
+ Accommodates end margin of this view and start margin of anchor view. -->
+ <attr name="layout_toStartOf" format="reference" />
+ <!-- Positions the start edge of this view to the end of the given anchor view ID.
+ Accommodates start margin of this view and end margin of anchor view. -->
+ <attr name="layout_toEndOf" format="reference" />
+ <!-- Makes the start edge of this view match the start edge of the given anchor view ID.
+ Accommodates start margin. -->
+ <attr name="layout_alignStart" format="reference" />
+ <!-- Makes the end edge of this view match the end edge of the given anchor view ID.
+ Accommodates end margin. -->
+ <attr name="layout_alignEnd" format="reference" />
+ <!-- If true, makes the start edge of this view match the start edge of the parent.
+ Accommodates start margin. -->
+ <attr name="layout_alignParentStart" format="boolean" />
+ <!-- If true, makes the end edge of this view match the end edge of the parent.
+ Accommodates end margin. -->
+ <attr name="layout_alignParentEnd" format="boolean" />
</declare-styleable>
<declare-styleable name="VerticalSlider_Layout">
<attr name="layout_scale" format="float" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 85c4503..9bc3c89 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -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>