diff options
17 files changed, 334 insertions, 51 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) { diff --git a/tests/BiDiTests/res/drawable/alphabet_a.png b/tests/BiDiTests/res/drawable/alphabet_a.png Binary files differnew file mode 100644 index 0000000..2a80ec1 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_a.png diff --git a/tests/BiDiTests/res/drawable/alphabet_b.png b/tests/BiDiTests/res/drawable/alphabet_b.png Binary files differnew file mode 100644 index 0000000..ac887ad --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_b.png diff --git a/tests/BiDiTests/res/drawable/alphabet_c.png b/tests/BiDiTests/res/drawable/alphabet_c.png Binary files differnew file mode 100644 index 0000000..f8cc5c6 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_c.png diff --git a/tests/BiDiTests/res/drawable/alphabet_d.png b/tests/BiDiTests/res/drawable/alphabet_d.png Binary files differnew file mode 100644 index 0000000..764dfe5 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_d.png diff --git a/tests/BiDiTests/res/drawable/alphabet_e.png b/tests/BiDiTests/res/drawable/alphabet_e.png Binary files differnew file mode 100644 index 0000000..dbd00e1 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_e.png diff --git a/tests/BiDiTests/res/drawable/alphabet_f.png b/tests/BiDiTests/res/drawable/alphabet_f.png Binary files differnew file mode 100644 index 0000000..f6a1bbe --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_f.png diff --git a/tests/BiDiTests/res/drawable/alphabet_g.png b/tests/BiDiTests/res/drawable/alphabet_g.png Binary files differnew file mode 100644 index 0000000..e9d360c --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_g.png diff --git a/tests/BiDiTests/res/drawable/alphabet_h.png b/tests/BiDiTests/res/drawable/alphabet_h.png Binary files differnew file mode 100644 index 0000000..cbc4eb1 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_h.png diff --git a/tests/BiDiTests/res/drawable/alphabet_i.png b/tests/BiDiTests/res/drawable/alphabet_i.png Binary files differnew file mode 100644 index 0000000..bae2103 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_i.png diff --git a/tests/BiDiTests/res/drawable/alphabet_j.png b/tests/BiDiTests/res/drawable/alphabet_j.png Binary files differnew file mode 100644 index 0000000..264c6a7 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_j.png diff --git a/tests/BiDiTests/res/layout/gallery_ltr.xml b/tests/BiDiTests/res/layout/gallery_ltr.xml new file mode 100644 index 0000000..d0e4168 --- /dev/null +++ b/tests/BiDiTests/res/layout/gallery_ltr.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/gallery_ltr" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="ltr"> + + <Gallery + android:id="@+id/galleryview" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:spacing="10dip" + /> + +</FrameLayout> diff --git a/tests/BiDiTests/res/layout/gallery_rtl.xml b/tests/BiDiTests/res/layout/gallery_rtl.xml new file mode 100644 index 0000000..c5c2f5c --- /dev/null +++ b/tests/BiDiTests/res/layout/gallery_rtl.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/gallery_rtl" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="rtl"> + + <Gallery + android:id="@+id/galleryview" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:spacing="10dip" + /> + +</FrameLayout> diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java index 6b38cc1..b45b98f 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java @@ -137,6 +137,8 @@ public class BiDiTestActivity extends Activity { addItem(result, "TextView Drawables LTR", BiDiTestTextViewDrawablesLtr.class, R.id.textview_drawables_ltr); addItem(result, "TextView Drawables RTL", BiDiTestTextViewDrawablesRtl.class, R.id.textview_drawables_rtl); + addItem(result, "Gallery LTR", BiDiTestGalleryLtr.class, R.id.gallery_ltr); + addItem(result, "Gallery RTL", BiDiTestGalleryRtl.class, R.id.gallery_rtl); return result; } @@ -147,4 +149,4 @@ public class BiDiTestActivity extends Activity { inflater.inflate(R.menu.main_menu, menu); return true; } -}
\ No newline at end of file +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryImages.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryImages.java new file mode 100644 index 0000000..adc17e1 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryImages.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.bidi; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; + +public class BiDiTestGalleryImages extends BaseAdapter { + int mGalleryItemBackground; + private Context mContext; + + private Integer[] mImageIds = { + R.drawable.alphabet_a, + R.drawable.alphabet_b, + R.drawable.alphabet_c, + R.drawable.alphabet_d, + R.drawable.alphabet_e, + R.drawable.alphabet_f, + R.drawable.alphabet_g, + R.drawable.alphabet_h, + R.drawable.alphabet_i, + R.drawable.alphabet_j, + }; + + public BiDiTestGalleryImages(Context c) { + mContext = c; + } + + @Override + public int getCount() { + return mImageIds.length; + } + + @Override + public Object getItem(int position) { + return position; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ImageView i = new ImageView(mContext); + i.setImageResource(mImageIds[position]); + i.setScaleType(ScaleType.CENTER_INSIDE); + return i; + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryLtr.java new file mode 100644 index 0000000..fa86b1a --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryLtr.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Gallery; + +public class BiDiTestGalleryLtr extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.gallery_ltr, container, false); + Gallery g = (Gallery) v.findViewById(R.id.galleryview); + g.setAdapter(new BiDiTestGalleryImages(this.getActivity().getBaseContext())); + return v; + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryRtl.java new file mode 100644 index 0000000..4cef658 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryRtl.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Gallery; + +public class BiDiTestGalleryRtl extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.gallery_rtl, container, false); + Gallery g = (Gallery) v.findViewById(R.id.galleryview); + g.setAdapter(new BiDiTestGalleryImages(this.getActivity().getBaseContext())); + return v; + } +} |