diff options
author | Fabrice Di Meglio <fdimeglio@google.com> | 2011-07-19 10:16:04 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-07-19 10:16:04 -0700 |
commit | 5f9fa8826887dd9a97617d5637a3862baf7b5913 (patch) | |
tree | b5eb275b58d2f800c35a368140e418204e1495ad /core | |
parent | 2e29de7cab35e4cf7c8f177b546cc95b101ed5c8 (diff) | |
parent | 3d0124f1764e57b18161b833b52964f3141243d1 (diff) | |
download | frameworks_base-5f9fa8826887dd9a97617d5637a3862baf7b5913.zip frameworks_base-5f9fa8826887dd9a97617d5637a3862baf7b5913.tar.gz frameworks_base-5f9fa8826887dd9a97617d5637a3862baf7b5913.tar.bz2 |
Merge "Test Gallery layout direction."
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/widget/Gallery.java | 183 |
1 files changed, 133 insertions, 50 deletions
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index 0ffd087..3f5b571 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -16,28 +16,28 @@ package android.widget; -import com.android.internal.R; - import android.annotation.Widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; +import android.view.ContextMenu.ContextMenuInfo; import android.view.GestureDetector; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.SoundEffectConstants; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; -import android.view.SoundEffectConstants; -import android.view.ContextMenu.ContextMenuInfo; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.Transformation; +import com.android.internal.R; + /** * A view that shows items in a center-locked, horizontally scrolling list. * <p> @@ -122,6 +122,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList * in the future. It will also trigger a selection changed. */ private Runnable mDisableSuppressSelectionChangedRunnable = new Runnable() { + @Override public void run() { mSuppressSelectionChanged = false; selectionChanged(); @@ -171,6 +172,12 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList * drag sends many onScrolls). */ private boolean mIsFirstScroll; + + /** + * If true, mFirstPosition is the position of the rightmost child, and + * the children are ordered right to left. + */ + private boolean mIsRtl = true; public Gallery(Context context) { this(context, null); @@ -418,7 +425,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList } int getLimitedMotionScrollAmount(boolean motionToLeft, int deltaX) { - int extremeItemPosition = motionToLeft ? mItemCount - 1 : 0; + int extremeItemPosition = motionToLeft != mIsRtl ? mItemCount - 1 : 0; View extremeChild = getChildAt(extremeItemPosition - mFirstPosition); if (extremeChild == null) { @@ -490,31 +497,40 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList if (toLeft) { final int galleryLeft = mPaddingLeft; for (int i = 0; i < numChildren; i++) { - final View child = getChildAt(i); + int n = mIsRtl ? (numChildren - 1 - i) : i; + final View child = getChildAt(n); if (child.getRight() >= galleryLeft) { break; } else { + start = n; count++; - mRecycler.put(firstPosition + i, child); + mRecycler.put(firstPosition + n, child); } } + if (!mIsRtl) { + start = 0; + } } else { final int galleryRight = getWidth() - mPaddingRight; for (int i = numChildren - 1; i >= 0; i--) { - final View child = getChildAt(i); + int n = mIsRtl ? numChildren - 1 - i : i; + final View child = getChildAt(n); if (child.getLeft() <= galleryRight) { break; } else { - start = i; + start = n; count++; - mRecycler.put(firstPosition + i, child); + mRecycler.put(firstPosition + n, child); } } + if (mIsRtl) { + start = 0; + } } detachViewsFromParent(start, count); - if (toLeft) { + if (toLeft != mIsRtl) { mFirstPosition += count; } } @@ -614,6 +630,8 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList @Override void layout(int delta, boolean animate) { + mIsRtl = isLayoutRtl(); + int childrenLeft = mSpinnerPadding.left; int childrenWidth = mRight - mLeft - mSpinnerPadding.left - mSpinnerPadding.right; @@ -676,6 +694,45 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList } private void fillToGalleryLeft() { + if (mIsRtl) { + fillToGalleryLeftRtl(); + } else { + fillToGalleryLeftLtr(); + } + } + + private void fillToGalleryLeftRtl() { + int itemSpacing = mSpacing; + int galleryLeft = mPaddingLeft; + int numChildren = getChildCount(); + int numItems = mItemCount; + + // Set state for initial iteration + View prevIterationView = getChildAt(numChildren - 1); + int curPosition; + int curRightEdge; + + if (prevIterationView != null) { + curPosition = mFirstPosition + numChildren; + curRightEdge = prevIterationView.getLeft() - itemSpacing; + } else { + // No children available! + mFirstPosition = curPosition = mItemCount - 1; + curRightEdge = mRight - mLeft - mPaddingRight; + mShouldStopFling = true; + } + + while (curRightEdge > galleryLeft && curPosition < mItemCount) { + prevIterationView = makeAndAddView(curPosition, curPosition - mSelectedPosition, + curRightEdge, false); + + // Set state for next iteration + curRightEdge = prevIterationView.getLeft() - itemSpacing; + curPosition++; + } + } + + private void fillToGalleryLeftLtr() { int itemSpacing = mSpacing; int galleryLeft = mPaddingLeft; @@ -708,6 +765,45 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList } private void fillToGalleryRight() { + if (mIsRtl) { + fillToGalleryRightRtl(); + } else { + fillToGalleryRightLtr(); + } + } + + private void fillToGalleryRightRtl() { + int itemSpacing = mSpacing; + int galleryRight = mRight - mLeft - mPaddingRight; + + // Set state for initial iteration + View prevIterationView = getChildAt(0); + int curPosition; + int curLeftEdge; + + if (prevIterationView != null) { + curPosition = mFirstPosition -1; + curLeftEdge = prevIterationView.getRight() + itemSpacing; + } else { + curPosition = 0; + curLeftEdge = mPaddingLeft; + mShouldStopFling = true; + } + + while (curLeftEdge < galleryRight && curPosition >= 0) { + prevIterationView = makeAndAddView(curPosition, curPosition - mSelectedPosition, + curLeftEdge, true); + + // Remember some state + mFirstPosition = curPosition; + + // Set state for next iteration + curLeftEdge = prevIterationView.getRight() + itemSpacing; + curPosition--; + } + } + + private void fillToGalleryRightLtr() { int itemSpacing = mSpacing; int galleryRight = mRight - mLeft - mPaddingRight; int numChildren = getChildCount(); @@ -745,18 +841,16 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList * * @param position Position in the gallery for the view to obtain * @param offset Offset from the selected position - * @param x X-coordintate indicating where this view should be placed. This + * @param x X-coordinate indicating where this view should be placed. This * will either be the left or right edge of the view, depending on - * the fromLeft paramter - * @param fromLeft Are we posiitoning views based on the left edge? (i.e., + * the fromLeft parameter + * @param fromLeft Are we positioning views based on the left edge? (i.e., * building from left to right)? * @return A view that has been added to the gallery */ - private View makeAndAddView(int position, int offset, int x, - boolean fromLeft) { + private View makeAndAddView(int position, int offset, int x, boolean fromLeft) { View child; - if (!mDataChanged) { child = mRecycler.get(position); if (child != null) { @@ -786,27 +880,26 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList /** * Helper for makeAndAddView to set the position of a view and fill out its - * layout paramters. + * layout parameters. * * @param child The view to position * @param offset Offset from the selected position - * @param x X-coordintate indicating where this view should be placed. This + * @param x X-coordinate indicating where this view should be placed. This * will either be the left or right edge of the view, depending on - * the fromLeft paramter - * @param fromLeft Are we posiitoning views based on the left edge? (i.e., + * the fromLeft parameter + * @param fromLeft Are we positioning views based on the left edge? (i.e., * building from left to right)? */ private void setUpChild(View child, int offset, int x, boolean fromLeft) { // Respect layout params that are already in the view. Otherwise // make some up... - Gallery.LayoutParams lp = (Gallery.LayoutParams) - child.getLayoutParams(); + Gallery.LayoutParams lp = (Gallery.LayoutParams) child.getLayoutParams(); if (lp == null) { lp = (Gallery.LayoutParams) generateDefaultLayoutParams(); } - addViewInLayout(child, fromLeft ? -1 : 0, lp); + addViewInLayout(child, fromLeft != mIsRtl ? -1 : 0, lp); child.setSelected(offset == 0); @@ -883,9 +976,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList return retValue; } - /** - * {@inheritDoc} - */ + @Override public boolean onSingleTapUp(MotionEvent e) { if (mDownTouchPosition >= 0) { @@ -905,9 +996,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList return false; } - /** - * {@inheritDoc} - */ + @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (!mShouldCallbackDuringFling) { @@ -926,9 +1015,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList return true; } - /** - * {@inheritDoc} - */ + @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (localLOGV) Log.v(TAG, String.valueOf(e2.getX() - e1.getX())); @@ -967,9 +1054,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList return true; } - /** - * {@inheritDoc} - */ + @Override public boolean onDown(MotionEvent e) { // Kill any existing fling/scroll @@ -1009,9 +1094,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList onUp(); } - /** - * {@inheritDoc} - */ + @Override public void onLongPress(MotionEvent e) { if (mDownTouchPosition < 0) { @@ -1025,9 +1108,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList // Unused methods from GestureDetector.OnGestureListener below - /** - * {@inheritDoc} - */ + @Override public void onShowPress(MotionEvent e) { } @@ -1164,6 +1245,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList dispatchPress(mSelectedChild); postDelayed(new Runnable() { + @Override public void run() { dispatchUnpress(); } @@ -1278,10 +1360,10 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList // Draw the selected child last return selectedIndex; } else if (i >= selectedIndex) { - // Move the children to the right of the selected child earlier one + // Move the children after the selected child earlier one return i + 1; } else { - // Keep the children to the left of the selected child the same + // Keep the children before the selected child the same return i; } } @@ -1306,7 +1388,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList * Responsible for fling behavior. Use {@link #startUsingVelocity(int)} to * initiate a fling. Each frame of the fling is handled in {@link #run()}. * A FlingRunnable will keep re-posting itself until the fling is done. - * */ private class FlingRunnable implements Runnable { /** @@ -1365,6 +1446,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList if (scrollIntoSlots) scrollIntoSlots(); } + @Override public void run() { if (mItemCount == 0) { @@ -1384,15 +1466,17 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList // Pretend that each frame of a fling scroll is a touch scroll if (delta > 0) { - // Moving towards the left. Use first view as mDownTouchPosition - mDownTouchPosition = mFirstPosition; + // Moving towards the left. Use leftmost view as mDownTouchPosition + mDownTouchPosition = mIsRtl ? (mFirstPosition + getChildCount() - 1) : + mFirstPosition; // Don't fling more than 1 screen delta = Math.min(getWidth() - mPaddingLeft - mPaddingRight - 1, delta); } else { - // Moving towards the right. Use last view as mDownTouchPosition + // Moving towards the right. Use rightmost view as mDownTouchPosition int offsetToLast = getChildCount() - 1; - mDownTouchPosition = mFirstPosition + offsetToLast; + mDownTouchPosition = mIsRtl ? mFirstPosition : + (mFirstPosition + getChildCount() - 1); // Don't fling more than 1 screen delta = Math.max(-(getWidth() - mPaddingRight - mPaddingLeft - 1), delta); @@ -1414,7 +1498,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList * Gallery extends LayoutParams to provide a place to hold current * Transformation information along with previous position/transformation * info. - * */ public static class LayoutParams extends ViewGroup.LayoutParams { public LayoutParams(Context c, AttributeSet attrs) { |