Skip to content

Commit 54e5a82

Browse files
Fabrice Di MeglioAndroid (Google) Code Review
authored andcommitted
Merge "Improve resolution of RTL related properties" into jb-mr1-dev
2 parents 9c38d6e + 23c89fd commit 54e5a82

File tree

3 files changed

+177
-69
lines changed

3 files changed

+177
-69
lines changed

core/java/android/view/View.java

Lines changed: 143 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,6 +2789,20 @@ static class TransformationInfo {
27892789
@ViewDebug.ExportedProperty(category = "padding")
27902790
int mUserPaddingEnd;
27912791

2792+
/**
2793+
* Whether a left padding has been defined during layout inflation.
2794+
*
2795+
* @hide
2796+
*/
2797+
boolean mUserPaddingLeftDefined = false;
2798+
2799+
/**
2800+
* Whether a right padding has been defined during layout inflation.
2801+
*
2802+
* @hide
2803+
*/
2804+
boolean mUserPaddingRightDefined = false;
2805+
27922806
/**
27932807
* Default undefined padding
27942808
*/
@@ -3195,8 +3209,11 @@ public View(Context context, AttributeSet attrs, int defStyle) {
31953209
boolean transformSet = false;
31963210

31973211
int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
3198-
31993212
int overScrollMode = mOverScrollMode;
3213+
boolean initializeScrollbars = false;
3214+
3215+
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
3216+
32003217
final int N = a.getIndexCount();
32013218
for (int i = 0; i < N; i++) {
32023219
int attr = a.getIndex(i);
@@ -3206,15 +3223,19 @@ public View(Context context, AttributeSet attrs, int defStyle) {
32063223
break;
32073224
case com.android.internal.R.styleable.View_padding:
32083225
padding = a.getDimensionPixelSize(attr, -1);
3226+
mUserPaddingLeftDefined = true;
3227+
mUserPaddingRightDefined = true;
32093228
break;
32103229
case com.android.internal.R.styleable.View_paddingLeft:
32113230
leftPadding = a.getDimensionPixelSize(attr, -1);
3231+
mUserPaddingLeftDefined = true;
32123232
break;
32133233
case com.android.internal.R.styleable.View_paddingTop:
32143234
topPadding = a.getDimensionPixelSize(attr, -1);
32153235
break;
32163236
case com.android.internal.R.styleable.View_paddingRight:
32173237
rightPadding = a.getDimensionPixelSize(attr, -1);
3238+
mUserPaddingRightDefined = true;
32183239
break;
32193240
case com.android.internal.R.styleable.View_paddingBottom:
32203241
bottomPadding = a.getDimensionPixelSize(attr, -1);
@@ -3359,12 +3380,12 @@ public View(Context context, AttributeSet attrs, int defStyle) {
33593380
if (scrollbars != SCROLLBARS_NONE) {
33603381
viewFlagValues |= scrollbars;
33613382
viewFlagMasks |= SCROLLBARS_MASK;
3362-
initializeScrollbars(a);
3383+
initializeScrollbars = true;
33633384
}
33643385
break;
33653386
//noinspection deprecation
33663387
case R.styleable.View_fadingEdge:
3367-
if (context.getApplicationInfo().targetSdkVersion >= ICE_CREAM_SANDWICH) {
3388+
if (targetSdkVersion >= ICE_CREAM_SANDWICH) {
33683389
// Ignore the attribute starting with ICS
33693390
break;
33703391
}
@@ -3496,12 +3517,11 @@ public void onClick(View v) {
34963517
}
34973518
}
34983519

3499-
a.recycle();
3500-
35013520
setOverScrollMode(overScrollMode);
35023521

3503-
// Cache user padding as we cannot fully resolve padding here (we dont have yet the resolved
3504-
// layout direction). Those cached values will be used later during padding resolution.
3522+
// Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
3523+
// the resolved layout direction). Those cached values will be used later during padding
3524+
// resolution.
35053525
mUserPaddingStart = startPadding;
35063526
mUserPaddingEnd = endPadding;
35073527

@@ -3529,6 +3549,12 @@ public void onClick(View v) {
35293549
setFlags(viewFlagValues, viewFlagMasks);
35303550
}
35313551

3552+
if (initializeScrollbars) {
3553+
initializeScrollbars(a);
3554+
}
3555+
3556+
a.recycle();
3557+
35323558
// Needs to be called after mViewFlags is set
35333559
if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
35343560
recomputePadding();
@@ -5533,10 +5559,13 @@ public void setLayoutDirection(int layoutDirection) {
55335559
// Reset the current layout direction and the resolved one
55345560
mPrivateFlags2 &= ~LAYOUT_DIRECTION_MASK;
55355561
resetResolvedLayoutDirection();
5536-
// Set the new layout direction (filtered) and ask for a layout pass
5562+
// Reset padding resolution
5563+
mPrivateFlags2 &= ~PADDING_RESOLVED;
5564+
// Set the new layout direction (filtered)
55375565
mPrivateFlags2 |=
55385566
((layoutDirection << LAYOUT_DIRECTION_MASK_SHIFT) & LAYOUT_DIRECTION_MASK);
5539-
resolvePadding();
5567+
resolveRtlProperties();
5568+
// ... and ask for a layout pass
55405569
requestLayout();
55415570
}
55425571
}
@@ -5552,6 +5581,11 @@ public void setLayoutDirection(int layoutDirection) {
55525581
@ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
55535582
})
55545583
public int getResolvedLayoutDirection() {
5584+
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
5585+
if (targetSdkVersion < JELLY_BEAN_MR1) {
5586+
mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED;
5587+
return LAYOUT_DIRECTION_LTR;
5588+
}
55555589
// The layout direction will be resolved only if needed
55565590
if ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED) != LAYOUT_DIRECTION_RESOLVED) {
55575591
resolveLayoutDirection();
@@ -9657,12 +9691,22 @@ public void setLayoutParams(ViewGroup.LayoutParams params) {
96579691
throw new NullPointerException("Layout parameters cannot be null");
96589692
}
96599693
mLayoutParams = params;
9694+
resolveLayoutParams();
96609695
if (mParent instanceof ViewGroup) {
96619696
((ViewGroup) mParent).onSetLayoutParams(this, params);
96629697
}
96639698
requestLayout();
96649699
}
96659700

9701+
/**
9702+
* Resolve the layout parameters depending on the resolved layout direction
9703+
*/
9704+
private void resolveLayoutParams() {
9705+
if (mLayoutParams != null) {
9706+
mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
9707+
}
9708+
}
9709+
96669710
/**
96679711
* Set the scrolled position of your view. This will cause a call to
96689712
* {@link #onScrollChanged(int, int, int, int)} and the view will be
@@ -11197,12 +11241,7 @@ protected void onAttachedToWindow() {
1119711241

1119811242
jumpDrawablesToCurrentState();
1119911243

11200-
// Order is important here: LayoutDirection MUST be resolved before Padding
11201-
// and TextDirection
11202-
resolveLayoutDirection();
11203-
resolvePadding();
11204-
resolveTextDirection();
11205-
resolveTextAlignment();
11244+
resolveRtlProperties();
1120611245

1120711246
clearAccessibilityFocus();
1120811247
if (isFocused()) {
@@ -11215,6 +11254,16 @@ protected void onAttachedToWindow() {
1121511254
}
1121611255
}
1121711256

11257+
void resolveRtlProperties() {
11258+
// Order is important here: LayoutDirection MUST be resolved first...
11259+
resolveLayoutDirection();
11260+
// ... then we can resolve the others properties depending on the resolved LayoutDirection.
11261+
resolvePadding();
11262+
resolveLayoutParams();
11263+
resolveTextDirection();
11264+
resolveTextAlignment();
11265+
}
11266+
1121811267
/**
1121911268
* @see #onScreenStateChanged(int)
1122011269
*/
@@ -11294,56 +11343,66 @@ public void resolveLayoutDirection() {
1129411343
public void onResolvedLayoutDirectionChanged() {
1129511344
}
1129611345

11346+
/**
11347+
* Return if padding has been resolved
11348+
*/
11349+
boolean isPaddingResolved() {
11350+
return (mPrivateFlags2 & PADDING_RESOLVED) != 0;
11351+
}
11352+
1129711353
/**
1129811354
* Resolve padding depending on layout direction.
1129911355
*/
1130011356
public void resolvePadding() {
11301-
// If the user specified the absolute padding (either with android:padding or
11302-
// android:paddingLeft/Top/Right/Bottom), use this padding, otherwise
11303-
// use the default padding or the padding from the background drawable
11304-
// (stored at this point in mPadding*)
11305-
int resolvedLayoutDirection = getResolvedLayoutDirection();
11306-
switch (resolvedLayoutDirection) {
11307-
case LAYOUT_DIRECTION_RTL:
11308-
// Start user padding override Right user padding. Otherwise, if Right user
11309-
// padding is not defined, use the default Right padding. If Right user padding
11310-
// is defined, just use it.
11311-
if (mUserPaddingStart != UNDEFINED_PADDING) {
11312-
mUserPaddingRight = mUserPaddingStart;
11313-
}
11314-
if (mUserPaddingRight == UNDEFINED_PADDING) {
11315-
mUserPaddingRight = mPaddingRight;
11316-
}
11317-
if (mUserPaddingEnd != UNDEFINED_PADDING) {
11318-
mUserPaddingLeft = mUserPaddingEnd;
11319-
}
11320-
if (mUserPaddingLeft == UNDEFINED_PADDING) {
11321-
mUserPaddingLeft = mPaddingLeft;
11322-
}
11323-
break;
11324-
case LAYOUT_DIRECTION_LTR:
11325-
default:
11326-
// Start user padding override Left user padding. Otherwise, if Left user
11327-
// padding is not defined, use the default left padding. If Left user padding
11328-
// is defined, just use it.
11329-
if (mUserPaddingStart != UNDEFINED_PADDING) {
11330-
mUserPaddingLeft = mUserPaddingStart;
11331-
}
11332-
if (mUserPaddingLeft == UNDEFINED_PADDING) {
11333-
mUserPaddingLeft = mPaddingLeft;
11334-
}
11335-
if (mUserPaddingEnd != UNDEFINED_PADDING) {
11336-
mUserPaddingRight = mUserPaddingEnd;
11337-
}
11338-
if (mUserPaddingRight == UNDEFINED_PADDING) {
11339-
mUserPaddingRight = mPaddingRight;
11340-
}
11341-
}
11357+
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
11358+
if (targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport()) {
11359+
// Pre Jelly Bean MR1 case (compatibility mode) OR no RTL support case:
11360+
// left / right padding are used if defined. If they are not defined and start / end
11361+
// padding are defined (e.g. in Frameworks resources), then we use start / end and
11362+
// resolve them as left / right (layout direction is not taken into account).
11363+
if (!mUserPaddingLeftDefined && mUserPaddingStart != UNDEFINED_PADDING) {
11364+
mUserPaddingLeft = mUserPaddingStart;
11365+
}
11366+
if (!mUserPaddingRightDefined && mUserPaddingEnd != UNDEFINED_PADDING) {
11367+
mUserPaddingRight = mUserPaddingEnd;
11368+
}
1134211369

11343-
mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
11370+
mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
11371+
11372+
internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight,
11373+
mUserPaddingBottom);
11374+
} else {
11375+
// Post Jelly Bean MR1 case: we need to take the resolved layout direction into account.
11376+
// If start / end padding are defined, they will be resolved (hence overriding) to
11377+
// left / right or right / left depending on the resolved layout direction.
11378+
// If start / end padding are not defined, use the left / right ones.
11379+
int resolvedLayoutDirection = getResolvedLayoutDirection();
11380+
switch (resolvedLayoutDirection) {
11381+
case LAYOUT_DIRECTION_RTL:
11382+
if (mUserPaddingStart != UNDEFINED_PADDING) {
11383+
mUserPaddingRight = mUserPaddingStart;
11384+
}
11385+
if (mUserPaddingEnd != UNDEFINED_PADDING) {
11386+
mUserPaddingLeft = mUserPaddingEnd;
11387+
}
11388+
break;
11389+
case LAYOUT_DIRECTION_LTR:
11390+
default:
11391+
if (mUserPaddingStart != UNDEFINED_PADDING) {
11392+
mUserPaddingLeft = mUserPaddingStart;
11393+
}
11394+
if (mUserPaddingEnd != UNDEFINED_PADDING) {
11395+
mUserPaddingRight = mUserPaddingEnd;
11396+
}
11397+
}
11398+
11399+
mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
11400+
11401+
internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight,
11402+
mUserPaddingBottom);
11403+
onPaddingChanged(resolvedLayoutDirection);
11404+
}
1134411405

11345-
internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
11346-
onPaddingChanged(resolvedLayoutDirection);
1134711406
mPrivateFlags2 |= PADDING_RESOLVED;
1134811407
}
1134911408

@@ -14016,6 +14075,8 @@ public void setBackgroundDrawable(Drawable background) {
1401614075
}
1401714076
background.setLayoutDirection(getResolvedLayoutDirection());
1401814077
if (background.getPadding(padding)) {
14078+
// Reset padding resolution
14079+
mPrivateFlags2 &= ~PADDING_RESOLVED;
1401914080
switch (background.getLayoutDirection()) {
1402014081
case LAYOUT_DIRECTION_RTL:
1402114082
internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
@@ -14112,13 +14173,19 @@ public Drawable getBackground() {
1411214173
* @param bottom the bottom padding in pixels
1411314174
*/
1411414175
public void setPadding(int left, int top, int right, int bottom) {
14176+
// Reset padding resolution
14177+
mPrivateFlags2 &= ~PADDING_RESOLVED;
14178+
1411514179
mUserPaddingStart = UNDEFINED_PADDING;
1411614180
mUserPaddingEnd = UNDEFINED_PADDING;
1411714181

1411814182
internalSetPadding(left, top, right, bottom);
1411914183
}
1412014184

14121-
void internalSetPadding(int left, int top, int right, int bottom) {
14185+
/**
14186+
* @hide
14187+
*/
14188+
protected void internalSetPadding(int left, int top, int right, int bottom) {
1412214189
mUserPaddingLeft = left;
1412314190
mUserPaddingRight = right;
1412414191
mUserPaddingBottom = bottom;
@@ -14193,6 +14260,9 @@ void internalSetPadding(int left, int top, int right, int bottom) {
1419314260
* @param bottom the bottom padding in pixels
1419414261
*/
1419514262
public void setPaddingRelative(int start, int top, int end, int bottom) {
14263+
// Reset padding resolution
14264+
mPrivateFlags2 &= ~PADDING_RESOLVED;
14265+
1419614266
mUserPaddingStart = start;
1419714267
mUserPaddingEnd = end;
1419814268

@@ -14234,6 +14304,9 @@ public int getPaddingBottom() {
1423414304
* @return the left padding in pixels
1423514305
*/
1423614306
public int getPaddingLeft() {
14307+
if (!isPaddingResolved()) {
14308+
resolvePadding();
14309+
}
1423714310
return mPaddingLeft;
1423814311
}
1423914312

@@ -14245,6 +14318,9 @@ public int getPaddingLeft() {
1424514318
* @return the start padding in pixels
1424614319
*/
1424714320
public int getPaddingStart() {
14321+
if (!isPaddingResolved()) {
14322+
resolvePadding();
14323+
}
1424814324
return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
1424914325
mPaddingRight : mPaddingLeft;
1425014326
}
@@ -14257,6 +14333,9 @@ public int getPaddingStart() {
1425714333
* @return the right padding in pixels
1425814334
*/
1425914335
public int getPaddingRight() {
14336+
if (!isPaddingResolved()) {
14337+
resolvePadding();
14338+
}
1426014339
return mPaddingRight;
1426114340
}
1426214341

@@ -14268,6 +14347,9 @@ public int getPaddingRight() {
1426814347
* @return the end padding in pixels
1426914348
*/
1427014349
public int getPaddingEnd() {
14350+
if (!isPaddingResolved()) {
14351+
resolvePadding();
14352+
}
1427114353
return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
1427214354
mPaddingLeft : mPaddingRight;
1427314355
}
@@ -14913,10 +14995,6 @@ public void requestLayout() {
1491314995
mPrivateFlags |= FORCE_LAYOUT;
1491414996
mPrivateFlags |= INVALIDATED;
1491514997

14916-
if (mLayoutParams != null) {
14917-
mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
14918-
}
14919-
1492014998
if (mParent != null && !mParent.isLayoutRequested()) {
1492114999
mParent.requestLayout();
1492215000
}
@@ -14960,7 +15038,7 @@ public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
1496015038
// first clears the measured dimension flag
1496115039
mPrivateFlags &= ~MEASURED_DIMENSION_SET;
1496215040

14963-
if ((mPrivateFlags2 & PADDING_RESOLVED) == 0) {
15041+
if (!isPaddingResolved()) {
1496415042
resolvePadding();
1496515043
}
1496615044

0 commit comments

Comments
 (0)