summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Di Meglio <fdimeglio@google.com>2013-06-11 19:13:54 -0700
committerFabrice Di Meglio <fdimeglio@google.com>2013-06-12 16:54:31 -0700
commitc4d712237cba31d0f34c6b96ea3533d4a8e1f028 (patch)
treecd1023c5df31040b4946dba140d3b4cb547c69ce
parent97f41383eb2bb098767ca153e470009fea810540 (diff)
downloadframeworks_base-c4d712237cba31d0f34c6b96ea3533d4a8e1f028.zip
frameworks_base-c4d712237cba31d0f34c6b96ea3533d4a8e1f028.tar.gz
frameworks_base-c4d712237cba31d0f34c6b96ea3533d4a8e1f028.tar.bz2
Fix bug #9302365 HorizontalScrollView is not RTL aware
- make FrameLayout capable of forcing a Gravity.LEFT (when there will be only one child with Gravity.RIGHT and wider than its parent like for HorizontalScrollView) - fix onLayout() so that it is forcing Gravity.LEFT if needed and setting correctly the initial mScrollX - also add restore/save from an instance state (by saving if the layout is RTL and the scroll position) Change-Id: Ida7ff4654c6a54a1696c2575af46f044dd1aabc8
-rw-r--r--core/java/android/widget/FrameLayout.java19
-rw-r--r--core/java/android/widget/HorizontalScrollView.java93
2 files changed, 104 insertions, 8 deletions
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 738f63b..691c941 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -267,12 +267,12 @@ public class FrameLayout extends ViewGroup {
return mForeground;
}
- private int getPaddingLeftWithForeground() {
+ int getPaddingLeftWithForeground() {
return mForegroundInPadding ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
mPaddingLeft + mForegroundPaddingLeft;
}
- private int getPaddingRightWithForeground() {
+ int getPaddingRightWithForeground() {
return mForegroundInPadding ? Math.max(mPaddingRight, mForegroundPaddingRight) :
mPaddingRight + mForegroundPaddingRight;
}
@@ -385,6 +385,11 @@ public class FrameLayout extends ViewGroup {
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ layoutChildren(left, top, right, bottom, false /* no force left gravity */);
+ }
+
+ void layoutChildren(int left, int top, int right, int bottom,
+ boolean forceLeftGravity) {
final int count = getChildCount();
final int parentLeft = getPaddingLeftWithForeground();
@@ -416,16 +421,16 @@ public class FrameLayout extends ViewGroup {
final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
- case Gravity.LEFT:
- childLeft = parentLeft + lp.leftMargin;
- break;
case Gravity.CENTER_HORIZONTAL:
childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
lp.leftMargin - lp.rightMargin;
break;
case Gravity.RIGHT:
- childLeft = parentRight - width - lp.rightMargin;
- break;
+ if (!forceLeftGravity) {
+ childLeft = parentRight - width - lp.rightMargin;
+ break;
+ }
+ case Gravity.LEFT:
default:
childLeft = parentLeft + lp.leftMargin;
}
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 55cfd27..61e791a 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -21,6 +21,8 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.FocusFinder;
@@ -133,6 +135,8 @@ public class HorizontalScrollView extends FrameLayout {
*/
private static final int INVALID_POINTER = -1;
+ private SavedState mSavedState;
+
public HorizontalScrollView(Context context) {
this(context, null);
}
@@ -1452,7 +1456,14 @@ public class HorizontalScrollView extends FrameLayout {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
+ // There is only one child
+ final View child = getChildAt(0);
+ final int childWidth = child.getMeasuredWidth();
+ final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
+ final int available = r - l - getPaddingLeftWithForeground() -
+ getPaddingRightWithForeground() - childParams.leftMargin - childParams.rightMargin;
+ final boolean forceLeftGravity = (childWidth > available);
+ layoutChildren(l, t, r, b, forceLeftGravity);
mIsLayoutDirty = false;
// Give a child focus if it needs it
if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
@@ -1460,6 +1471,28 @@ public class HorizontalScrollView extends FrameLayout {
}
mChildToScrollTo = null;
+ if (!hasLayout()) {
+ final int scrollRange = Math.max(0,
+ childWidth - (r - l - mPaddingLeft - mPaddingRight));
+ if (mSavedState != null) {
+ if (isLayoutRtl() == mSavedState.isLayoutRtl) {
+ mScrollX = mSavedState.scrollPosition;
+ } else {
+ mScrollX = scrollRange - mSavedState.scrollPosition;
+ }
+ } else {
+ if (isLayoutRtl()) {
+ mScrollX = scrollRange - mScrollX;
+ } // mScrollX default value is "0" for LTR
+ }
+ // Don't forget to clamp
+ if (mScrollX > scrollRange) {
+ mScrollX = scrollRange;
+ } else if (mScrollX < 0) {
+ mScrollX = 0;
+ }
+ }
+
// Calling this with the present values causes it to re-claim them
scrollTo(mScrollX, mScrollY);
}
@@ -1604,4 +1637,62 @@ public class HorizontalScrollView extends FrameLayout {
}
return n;
}
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ mSavedState = ss;
+ requestLayout();
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ SavedState ss = new SavedState(superState);
+ ss.scrollPosition = mScrollX;
+ ss.isLayoutRtl = isLayoutRtl();
+ return ss;
+ }
+
+ static class SavedState extends BaseSavedState {
+ public int scrollPosition;
+ public boolean isLayoutRtl;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public SavedState(Parcel source) {
+ super(source);
+ scrollPosition = source.readInt();
+ isLayoutRtl = (source.readInt() == 0) ? true : false;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(scrollPosition);
+ dest.writeInt(isLayoutRtl ? 1 : 0);
+ }
+
+ @Override
+ public String toString() {
+ return "HorizontalScrollView.SavedState{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " scrollPosition=" + scrollPosition
+ + " isLayoutRtl=" + isLayoutRtl + "}";
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR
+ = new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
}