am 54e5a825: Merge "Improve resolution of RTL related properties" into jb-mr1-dev

* commit '54e5a825f2f82839e63e37ec32dc1b0757e95dfe':
  Improve resolution of RTL related properties
This commit is contained in:
Fabrice Di Meglio
2012-08-17 10:12:18 -07:00
committed by Android Git Automerger
3 changed files with 177 additions and 69 deletions

View File

@@ -2789,6 +2789,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.ExportedProperty(category = "padding")
int mUserPaddingEnd;
/**
* Whether a left padding has been defined during layout inflation.
*
* @hide
*/
boolean mUserPaddingLeftDefined = false;
/**
* Whether a right padding has been defined during layout inflation.
*
* @hide
*/
boolean mUserPaddingRightDefined = false;
/**
* Default undefined padding
*/
@@ -3195,8 +3209,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
boolean transformSet = false;
int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
int overScrollMode = mOverScrollMode;
boolean initializeScrollbars = false;
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
@@ -3206,15 +3223,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
break;
case com.android.internal.R.styleable.View_padding:
padding = a.getDimensionPixelSize(attr, -1);
mUserPaddingLeftDefined = true;
mUserPaddingRightDefined = true;
break;
case com.android.internal.R.styleable.View_paddingLeft:
leftPadding = a.getDimensionPixelSize(attr, -1);
mUserPaddingLeftDefined = true;
break;
case com.android.internal.R.styleable.View_paddingTop:
topPadding = a.getDimensionPixelSize(attr, -1);
break;
case com.android.internal.R.styleable.View_paddingRight:
rightPadding = a.getDimensionPixelSize(attr, -1);
mUserPaddingRightDefined = true;
break;
case com.android.internal.R.styleable.View_paddingBottom:
bottomPadding = a.getDimensionPixelSize(attr, -1);
@@ -3359,12 +3380,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (scrollbars != SCROLLBARS_NONE) {
viewFlagValues |= scrollbars;
viewFlagMasks |= SCROLLBARS_MASK;
initializeScrollbars(a);
initializeScrollbars = true;
}
break;
//noinspection deprecation
case R.styleable.View_fadingEdge:
if (context.getApplicationInfo().targetSdkVersion >= ICE_CREAM_SANDWICH) {
if (targetSdkVersion >= ICE_CREAM_SANDWICH) {
// Ignore the attribute starting with ICS
break;
}
@@ -3496,12 +3517,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
a.recycle();
setOverScrollMode(overScrollMode);
// Cache user padding as we cannot fully resolve padding here (we dont have yet the resolved
// layout direction). Those cached values will be used later during padding resolution.
// Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
// the resolved layout direction). Those cached values will be used later during padding
// resolution.
mUserPaddingStart = startPadding;
mUserPaddingEnd = endPadding;
@@ -3529,6 +3549,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setFlags(viewFlagValues, viewFlagMasks);
}
if (initializeScrollbars) {
initializeScrollbars(a);
}
a.recycle();
// Needs to be called after mViewFlags is set
if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
recomputePadding();
@@ -5533,10 +5559,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Reset the current layout direction and the resolved one
mPrivateFlags2 &= ~LAYOUT_DIRECTION_MASK;
resetResolvedLayoutDirection();
// Set the new layout direction (filtered) and ask for a layout pass
// Reset padding resolution
mPrivateFlags2 &= ~PADDING_RESOLVED;
// Set the new layout direction (filtered)
mPrivateFlags2 |=
((layoutDirection << LAYOUT_DIRECTION_MASK_SHIFT) & LAYOUT_DIRECTION_MASK);
resolvePadding();
resolveRtlProperties();
// ... and ask for a layout pass
requestLayout();
}
}
@@ -5552,6 +5581,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
})
public int getResolvedLayoutDirection() {
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
if (targetSdkVersion < JELLY_BEAN_MR1) {
mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED;
return LAYOUT_DIRECTION_LTR;
}
// The layout direction will be resolved only if needed
if ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED) != LAYOUT_DIRECTION_RESOLVED) {
resolveLayoutDirection();
@@ -9657,12 +9691,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
throw new NullPointerException("Layout parameters cannot be null");
}
mLayoutParams = params;
resolveLayoutParams();
if (mParent instanceof ViewGroup) {
((ViewGroup) mParent).onSetLayoutParams(this, params);
}
requestLayout();
}
/**
* Resolve the layout parameters depending on the resolved layout direction
*/
private void resolveLayoutParams() {
if (mLayoutParams != null) {
mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
}
}
/**
* Set the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
@@ -11197,12 +11241,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
jumpDrawablesToCurrentState();
// Order is important here: LayoutDirection MUST be resolved before Padding
// and TextDirection
resolveLayoutDirection();
resolvePadding();
resolveTextDirection();
resolveTextAlignment();
resolveRtlProperties();
clearAccessibilityFocus();
if (isFocused()) {
@@ -11215,6 +11254,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
void resolveRtlProperties() {
// Order is important here: LayoutDirection MUST be resolved first...
resolveLayoutDirection();
// ... then we can resolve the others properties depending on the resolved LayoutDirection.
resolvePadding();
resolveLayoutParams();
resolveTextDirection();
resolveTextAlignment();
}
/**
* @see #onScreenStateChanged(int)
*/
@@ -11294,56 +11343,66 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void onResolvedLayoutDirectionChanged() {
}
/**
* Return if padding has been resolved
*/
boolean isPaddingResolved() {
return (mPrivateFlags2 & PADDING_RESOLVED) != 0;
}
/**
* Resolve padding depending on layout direction.
*/
public void resolvePadding() {
// If the user specified the absolute padding (either with android:padding or
// android:paddingLeft/Top/Right/Bottom), use this padding, otherwise
// use the default padding or the padding from the background drawable
// (stored at this point in mPadding*)
int resolvedLayoutDirection = getResolvedLayoutDirection();
switch (resolvedLayoutDirection) {
case LAYOUT_DIRECTION_RTL:
// Start user padding override Right user padding. Otherwise, if Right user
// padding is not defined, use the default Right padding. If Right user padding
// is defined, just use it.
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingStart;
}
if (mUserPaddingRight == UNDEFINED_PADDING) {
mUserPaddingRight = mPaddingRight;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingEnd;
}
if (mUserPaddingLeft == UNDEFINED_PADDING) {
mUserPaddingLeft = mPaddingLeft;
}
break;
case LAYOUT_DIRECTION_LTR:
default:
// Start user padding override Left user padding. Otherwise, if Left user
// padding is not defined, use the default left padding. If Left user padding
// is defined, just use it.
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingStart;
}
if (mUserPaddingLeft == UNDEFINED_PADDING) {
mUserPaddingLeft = mPaddingLeft;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingEnd;
}
if (mUserPaddingRight == UNDEFINED_PADDING) {
mUserPaddingRight = mPaddingRight;
}
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
if (targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport()) {
// Pre Jelly Bean MR1 case (compatibility mode) OR no RTL support case:
// left / right padding are used if defined. If they are not defined and start / end
// padding are defined (e.g. in Frameworks resources), then we use start / end and
// resolve them as left / right (layout direction is not taken into account).
if (!mUserPaddingLeftDefined && mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingStart;
}
if (!mUserPaddingRightDefined && mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingEnd;
}
mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight,
mUserPaddingBottom);
} else {
// Post Jelly Bean MR1 case: we need to take the resolved layout direction into account.
// If start / end padding are defined, they will be resolved (hence overriding) to
// left / right or right / left depending on the resolved layout direction.
// If start / end padding are not defined, use the left / right ones.
int resolvedLayoutDirection = getResolvedLayoutDirection();
switch (resolvedLayoutDirection) {
case LAYOUT_DIRECTION_RTL:
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingStart;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingEnd;
}
break;
case LAYOUT_DIRECTION_LTR:
default:
if (mUserPaddingStart != UNDEFINED_PADDING) {
mUserPaddingLeft = mUserPaddingStart;
}
if (mUserPaddingEnd != UNDEFINED_PADDING) {
mUserPaddingRight = mUserPaddingEnd;
}
}
mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight,
mUserPaddingBottom);
onPaddingChanged(resolvedLayoutDirection);
}
mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
onPaddingChanged(resolvedLayoutDirection);
mPrivateFlags2 |= PADDING_RESOLVED;
}
@@ -14016,6 +14075,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
background.setLayoutDirection(getResolvedLayoutDirection());
if (background.getPadding(padding)) {
// Reset padding resolution
mPrivateFlags2 &= ~PADDING_RESOLVED;
switch (background.getLayoutDirection()) {
case LAYOUT_DIRECTION_RTL:
internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
@@ -14112,13 +14173,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param bottom the bottom padding in pixels
*/
public void setPadding(int left, int top, int right, int bottom) {
// Reset padding resolution
mPrivateFlags2 &= ~PADDING_RESOLVED;
mUserPaddingStart = UNDEFINED_PADDING;
mUserPaddingEnd = UNDEFINED_PADDING;
internalSetPadding(left, top, right, bottom);
}
void internalSetPadding(int left, int top, int right, int bottom) {
/**
* @hide
*/
protected void internalSetPadding(int left, int top, int right, int bottom) {
mUserPaddingLeft = left;
mUserPaddingRight = right;
mUserPaddingBottom = bottom;
@@ -14193,6 +14260,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param bottom the bottom padding in pixels
*/
public void setPaddingRelative(int start, int top, int end, int bottom) {
// Reset padding resolution
mPrivateFlags2 &= ~PADDING_RESOLVED;
mUserPaddingStart = start;
mUserPaddingEnd = end;
@@ -14234,6 +14304,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return the left padding in pixels
*/
public int getPaddingLeft() {
if (!isPaddingResolved()) {
resolvePadding();
}
return mPaddingLeft;
}
@@ -14245,6 +14318,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return the start padding in pixels
*/
public int getPaddingStart() {
if (!isPaddingResolved()) {
resolvePadding();
}
return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
mPaddingRight : mPaddingLeft;
}
@@ -14257,6 +14333,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return the right padding in pixels
*/
public int getPaddingRight() {
if (!isPaddingResolved()) {
resolvePadding();
}
return mPaddingRight;
}
@@ -14268,6 +14347,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return the end padding in pixels
*/
public int getPaddingEnd() {
if (!isPaddingResolved()) {
resolvePadding();
}
return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
mPaddingLeft : mPaddingRight;
}
@@ -14913,10 +14995,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags |= FORCE_LAYOUT;
mPrivateFlags |= INVALIDATED;
if (mLayoutParams != null) {
mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
}
if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
@@ -14960,7 +15038,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// first clears the measured dimension flag
mPrivateFlags &= ~MEASURED_DIMENSION_SET;
if ((mPrivateFlags2 & PADDING_RESOLVED) == 0) {
if (!isPaddingResolved()) {
resolvePadding();
}

View File

@@ -2517,8 +2517,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
super.dispatchDetachedFromWindow();
}
/**
* @hide
*/
@Override
void internalSetPadding(int left, int top, int right, int bottom) {
protected void internalSetPadding(int left, int top, int right, int bottom) {
super.internalSetPadding(left, top, right, bottom);
if ((mPaddingLeft | mPaddingTop | mPaddingRight | mPaddingBottom) != 0) {
@@ -3372,6 +3375,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (child.hasTransientState()) {
childHasTransientStateChanged(child, true);
}
if (child.getLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) {
child.resetResolvedLayoutDirection();
child.resolveRtlProperties();
}
}
private void addInArray(View child, int index) {
@@ -3597,6 +3605,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
childHasTransientStateChanged(view, false);
}
view.resetResolvedLayoutDirection();
onViewRemoved(view);
needGlobalAttributesUpdate(false);

View File

@@ -151,7 +151,7 @@ public class CheckedTextView extends TextView implements Checkable {
mCheckMarkWidth = 0;
}
mCheckMarkDrawable = d;
// Do padding resolution. This will call setPadding() and do a requestLayout() if needed.
// Do padding resolution. This will call internalSetPadding() and do a requestLayout() if needed.
resolvePadding();
}
@@ -169,6 +169,19 @@ public class CheckedTextView extends TextView implements Checkable {
return mCheckMarkDrawable;
}
/**
* @hide
*/
@Override
protected void internalSetPadding(int left, int top, int right, int bottom) {
super.internalSetPadding(left, top, right, bottom);
if (isLayoutRtl()) {
mBasePadding = mUserPaddingLeft;
} else {
mBasePadding = mUserPaddingRight;
}
}
@Override
public void onPaddingChanged(int layoutDirection) {
int newPadding = (mCheckMarkDrawable != null) ?
@@ -221,8 +234,15 @@ public class CheckedTextView extends TextView implements Checkable {
final int width = getWidth();
final int top = y;
final int bottom = top + height;
final int left = isLayoutRtl ? getPaddingEnd() : width - getPaddingEnd();
final int right = left + mCheckMarkWidth;
final int left;
final int right;
if (isLayoutRtl) {
right = getPaddingEnd();
left = right - mCheckMarkWidth;
} else {
left = width - getPaddingEnd();
right = left + mCheckMarkWidth;
}
checkMarkDrawable.setBounds( left, top, right, bottom);
checkMarkDrawable.draw(canvas);
}