diff options
-rw-r--r-- | src/com/android/browser/NavScreen.java | 2 | ||||
-rw-r--r-- | src/com/android/browser/NavTabGallery.java | 36 | ||||
-rw-r--r-- | src/com/android/browser/view/Gallery.java | 77 |
3 files changed, 99 insertions, 16 deletions
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java index f52ef88..a361136 100644 --- a/src/com/android/browser/NavScreen.java +++ b/src/com/android/browser/NavScreen.java @@ -247,7 +247,7 @@ public class NavScreen extends RelativeLayout @Override public void onClick(View v) { if (tabview.isClose(v)) { - onCloseTab(tab); + mScroller.animateOut(tabview); } else if (tabview.isTitle(v)) { mScroller.setSelection(position); switchToSelected(); diff --git a/src/com/android/browser/NavTabGallery.java b/src/com/android/browser/NavTabGallery.java index 0cd1f82..8247a5d 100644 --- a/src/com/android/browser/NavTabGallery.java +++ b/src/com/android/browser/NavTabGallery.java @@ -40,6 +40,7 @@ public class NavTabGallery extends Gallery { private OnRemoveListener mRemoveListener; private boolean mBlockUpCallback; + private Animator mAnimator; public NavTabGallery(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); @@ -76,13 +77,15 @@ public class NavTabGallery extends Gallery { @Override protected void onOrthoDrag(View v, MotionEvent down, MotionEvent move, float distance) { - offsetView(v, - distance); + if (mAnimator == null) { + offsetView(v, - distance); + } } @Override protected void onOrthoFling(View v, MotionEvent down, MotionEvent move, float velocity) { - if (Math.abs(velocity) > MIN_VELOCITY) { + if ((mAnimator == null) && (Math.abs(velocity) > MIN_VELOCITY)) { mBlockUpCallback = true; animateOut(v, velocity); } @@ -90,6 +93,7 @@ public class NavTabGallery extends Gallery { @Override protected void onUp(View downView) { + if (mAnimator != null) return; if (mBlockUpCallback) { mBlockUpCallback = false; return; @@ -118,8 +122,13 @@ public class NavTabGallery extends Gallery { } } - private void animateOut(View v, float velocity) { - final int position = mDownTouchPosition; + protected void animateOut(View v) { + animateOut(v, -MIN_VELOCITY); + } + + private void animateOut(final View v, float velocity) { + if (mAnimator != null) return; + final int position = mFirstPosition + indexOfChild(v); int target = 0; if (velocity < 0) { target = mHorizontal ? -v.getHeight() : - v.getWidth(); @@ -128,21 +137,28 @@ public class NavTabGallery extends Gallery { } int distance = target - (mHorizontal ? v.getTop() : v.getLeft()); long duration = (long) (Math.abs(distance) * 1000 / Math.abs(velocity)); - ObjectAnimator animator = null; if (mHorizontal) { - animator = ObjectAnimator.ofFloat(v, TRANSLATION_Y, 0, target); + mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_Y, 0, target); } else { - animator = ObjectAnimator.ofFloat(v, TRANSLATION_X, 0, target); + mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_X, 0, target); } - animator.setDuration(duration); - animator.addListener(new AnimatorListenerAdapter() { + mAnimator.setDuration(duration); + mAnimator.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator a) { if (mRemoveListener != null) { + boolean needsGap = position < (mAdapter.getCount() - 1); + if (needsGap) { + setGapPosition(position, mHorizontal ? v.getWidth() : v.getHeight()); + } mRemoveListener.onRemovePosition(position); + if (!needsGap && position > 0) { + scrollToChild(position - 1); + } + mAnimator = null; } } }); - animator.start(); + mAnimator.start(); } } diff --git a/src/com/android/browser/view/Gallery.java b/src/com/android/browser/view/Gallery.java index d9c172e..59e710d 100644 --- a/src/com/android/browser/view/Gallery.java +++ b/src/com/android/browser/view/Gallery.java @@ -16,6 +16,9 @@ package com.android.browser.view; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.TypedArray; import android.database.DataSetObserver; @@ -64,7 +67,7 @@ public class Gallery extends ViewGroup implements private RecycleBin mRecycler; protected boolean mHorizontal; - private int mFirstPosition; + protected int mFirstPosition; private int mItemCount; private boolean mDataChanged; @@ -89,6 +92,10 @@ public class Gallery extends ViewGroup implements private OnItemSelectedListener mOnItemSelectedListener; private SelectionNotifier mSelectionNotifier; + private int mGapPosition; + private int mGap; + private Animator mGapAnimator; + /** * Sets mSuppressSelectionChanged = false. This is used to set it to false * in the future. It will also trigger a selection changed. @@ -161,6 +168,10 @@ public class Gallery extends ViewGroup implements mTouchSlop = configuration.getScaledTouchSlop(); setFocusable(true); setWillNotDraw(false); + mGapPosition = INVALID_POSITION; + mGap = 0; + // proguard + setGap(getGap()); } /** @@ -192,6 +203,29 @@ public class Gallery extends ViewGroup implements requestLayout(); } + /** + * define a visual gap in the list of items + * the gap is rendered in front (left or above) + * the given position + * @param position + * @param gap + */ + public void setGapPosition(int position, int gap) { + mGapPosition = position; + mGap = gap; + } + + public void setGap(int gap) { + if (mGapPosition != INVALID_POSITION) { + mGap = gap; + layout(0, false); + } + } + + public int getGap() { + return mGap; + } + public void setAdapter(BaseAdapter adapter) { mAdapter = adapter; if (mAdapter != null) { @@ -214,6 +248,9 @@ public class Gallery extends ViewGroup implements void handleDataChanged() { if (mAdapter != null) { + if (mGapAnimator != null) { + mGapAnimator.cancel(); + } resetList(); mItemCount = mAdapter.getCount(); // checkFocus(); @@ -226,7 +263,21 @@ public class Gallery extends ViewGroup implements // Nothing selected checkSelectionChanged(); } - layout(0, false); + if (mGapPosition > INVALID_POSITION) { + mGapAnimator = ObjectAnimator.ofInt(this, "gap", mGap, 0); + mGapAnimator.setDuration(250); + mGapAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator a) { + mGapPosition = INVALID_POSITION; + mGap = 0; + mGapAnimator = null; + } + }); + mGapAnimator.start(); + } else { + layout(0, false); + } } else { // checkFocus(); mOldSelectedPosition = INVALID_POSITION; @@ -373,7 +424,7 @@ public class Gallery extends ViewGroup implements * @param deltaX * Change in X from the previous event. */ - void trackMotionScroll(int deltaX) { + protected void trackMotionScroll(int deltaX) { if (getChildCount() == 0) { return; } @@ -587,6 +638,9 @@ public class Gallery extends ViewGroup implements } fillToGalleryRight(); fillToGalleryLeft(); + if (mGapPosition > INVALID_POSITION) { + adjustGap(); + } mRecycler.clear(); invalidate(); checkSelectionChanged(); @@ -594,6 +648,19 @@ public class Gallery extends ViewGroup implements updateSelectedItemMetadata(); } + void adjustGap() { + for (int i = 0; i < getChildCount(); i++) { + int pos = i + mFirstPosition; + if (pos >= mGapPosition) { + if (mHorizontal) { + getChildAt(i).offsetLeftAndRight(mGap); + } else { + getChildAt(i).offsetTopAndBottom(mGap); + } + } + } + } + void recycleAllViews() { final int childCount = getChildCount(); final RecycleBin recycleBin = mRecycler; @@ -619,7 +686,7 @@ public class Gallery extends ViewGroup implements // No children available! curPosition = 0; curRightEdge = (mHorizontal ? mRight - mLeft - mPaddingRight - : mBottom - mBottom - mPaddingBottom); + : mBottom - mTop - mPaddingBottom); mShouldStopFling = true; } while (curRightEdge > galleryLeft && curPosition >= 0) { @@ -1122,7 +1189,7 @@ public class Gallery extends ViewGroup implements } } - private boolean scrollToChild(int childPosition) { + protected boolean scrollToChild(int childPosition) { View child = getChildAt(childPosition); if (child != null) { int distance = getCenterOfGallery() - getCenterOfView(child); |