diff options
| author | Fabrice Di Meglio <fdimeglio@google.com> | 2013-06-11 19:13:54 -0700 |
|---|---|---|
| committer | Fabrice Di Meglio <fdimeglio@google.com> | 2013-06-12 16:54:31 -0700 |
| commit | c4d712237cba31d0f34c6b96ea3533d4a8e1f028 (patch) | |
| tree | cd1023c5df31040b4946dba140d3b4cb547c69ce | |
| parent | 97f41383eb2bb098767ca153e470009fea810540 (diff) | |
| download | frameworks_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.java | 19 | ||||
| -rw-r--r-- | core/java/android/widget/HorizontalScrollView.java | 93 |
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]; + } + }; + } } |
