diff options
author | Hongwei Wang <hwwang@google.com> | 2013-09-16 15:12:56 -0700 |
---|---|---|
committer | Hongwei Wang <hwwang@google.com> | 2013-09-16 20:40:20 -0700 |
commit | 4911300ae3fa7ab186ee271f8bc431b65a819a3c (patch) | |
tree | 6e820b603b6475259b3d26a0555ee883bc355c81 | |
parent | f796309c9492475cc1911d22fda5319d6d4c4853 (diff) |
Crossfade when drop to the position
Bug: 10686781
Change-Id: I8e5546b1eb8f914054e9525e8d763928d35836a8
-rw-r--r-- | res/layout/phone_favorites_fragment.xml | 6 | ||||
-rw-r--r-- | res/values/animation_constants.xml | 4 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteFragment.java | 65 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteListView.java | 84 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoriteTileView.java | 10 | ||||
-rw-r--r-- | src/com/android/dialer/list/PhoneFavoritesTileAdapter.java | 4 |
6 files changed, 101 insertions, 72 deletions
diff --git a/res/layout/phone_favorites_fragment.xml b/res/layout/phone_favorites_fragment.xml index 6023fc84e..4d3abf490 100644 --- a/res/layout/phone_favorites_fragment.xml +++ b/res/layout/phone_favorites_fragment.xml @@ -45,5 +45,11 @@ android:layout_marginTop="@dimen/empty_message_top_margin" android:textColor="?android:attr/textColorSecondary" android:textAppearance="?android:attr/textAppearanceLarge"/> + + <ImageView + android:id="@+id/contact_tile_drag_shadow_overlay" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone"/> </FrameLayout> </LinearLayout> diff --git a/res/values/animation_constants.xml b/res/values/animation_constants.xml index 77b762739..b41b316ff 100644 --- a/res/values/animation_constants.xml +++ b/res/values/animation_constants.xml @@ -15,7 +15,7 @@ ~ limitations under the License --> <resources> - <integer name="fade_duration">250</integer> + <integer name="fade_duration">300</integer> <!-- Swipe constants --> <integer name="swipe_escape_velocity">100</integer> @@ -27,4 +27,4 @@ <dimen name="min_swipe">5dip</dimen> <dimen name="min_vert">10dip</dimen> <dimen name="min_lock">20dip</dimen> -</resources>
\ No newline at end of file +</resources> diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java index d8179e797..a9613478a 100644 --- a/src/com/android/dialer/list/PhoneFavoriteFragment.java +++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java @@ -33,6 +33,7 @@ import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; +import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; @@ -66,7 +67,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen private static final String TAG = PhoneFavoriteFragment.class.getSimpleName(); private static final boolean DEBUG = true; - private static final int ANIMATION_DURATION = 300; + private int mAnimationDuration; /** * Used with LoaderManager. @@ -182,6 +183,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen if (DEBUG) Log.d(TAG, "onCreate()"); super.onCreate(savedState); + mAnimationDuration = getResources().getInteger(R.integer.fade_duration); mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(), this, 1); final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); @@ -213,6 +215,10 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen mListView.setOnItemSwipeListener(mContactTileAdapter); mListView.setOnDragDropListener(mContactTileAdapter); + final ImageView dragShadowOverlay = + (ImageView) listLayout.findViewById(R.id.contact_tile_drag_shadow_overlay); + mListView.setDragShadowOverlay(dragShadowOverlay); + mEmptyView = inflater.inflate(R.layout.phone_no_favorites, mListView, false); mShowAllContactsButton = inflater.inflate(R.layout.show_all_contact_button, mListView, @@ -372,25 +378,13 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen final ContactEntry entry = list.get(i); final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id); - // Skip animation for this view if the caller specified that it should be - // kept in place - if (containsId(idsInPlace, itemId)) continue; - - Integer startLeft = mItemIdLeftMap.get(itemId); - int left = child.getLeft(); - if (DEBUG) { - Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i + - " Left: " + left); - } - if (startLeft != null) { - if (startLeft != left) { - int delta = startLeft - left; - child.setTranslationX(delta); - child.animate().setDuration(ANIMATION_DURATION).translationX(0); - } + if (containsId(idsInPlace, itemId)) { + child.setAlpha(0.0f); + child.animate().alpha(1.0f) + .setDuration(mAnimationDuration) + .start(); + break; } - // No need to worry about horizontal offsets of new views that come into view since - // there is no horizontal scrolling involved. } } @@ -424,33 +418,12 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen final long itemId = mAdapter.getItemId(position); - // Skip animation for this view if the caller specified that it should be - // kept in place - if (containsId(idsInPlace, itemId)) continue; - - Integer startTop = mItemIdTopMap.get(itemId); - final int top = child.getTop(); - if (DEBUG) { - Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i + - " Top: " + top); - } - int delta = 0; - if (startTop != null) { - if (startTop != top) { - delta = startTop - top; - } - } else if (!mItemIdLeftMap.containsKey(itemId)) { - // Animate new views along with the others. The catch is that they did not - // exist in the start state, so we must calculate their starting position - // based on neighboring views. - int childHeight = child.getHeight() + mListView.getDividerHeight(); - startTop = top + (i > 0 ? childHeight : -childHeight); - delta = startTop - top; - } - - if (delta != 0) { - child.setTranslationY(delta); - child.animate().setDuration(ANIMATION_DURATION).translationY(0); + if (containsId(idsInPlace, itemId)) { + child.setAlpha(0.0f); + child.animate().alpha(1.0f) + .setDuration(mAnimationDuration) + .start(); + break; } } mItemIdTopMap.clear(); diff --git a/src/com/android/dialer/list/PhoneFavoriteListView.java b/src/com/android/dialer/list/PhoneFavoriteListView.java index 4ce5df15f..04bbe6b08 100644 --- a/src/com/android/dialer/list/PhoneFavoriteListView.java +++ b/src/com/android/dialer/list/PhoneFavoriteListView.java @@ -17,11 +17,11 @@ package com.android.dialer.list; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Context; import android.content.res.Configuration; import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; import android.os.Handler; import android.util.AttributeSet; import android.util.Log; @@ -29,6 +29,8 @@ import android.view.DragEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; +import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.ListView; import com.android.dialer.R; @@ -66,7 +68,10 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba private boolean mIsDragScrollerRunning = false; private int mTouchDownForDragStartX; private int mTouchDownForDragStartY; + private Bitmap mDragShadowBitmap; + private ImageView mDragShadowOverlay; + private int mAnimationDuration; // X and Y offsets inside the item from where the user grabbed to the // child's left coordinate. This is used to aid in the drawing of the drag shadow. @@ -78,8 +83,7 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba private int mDragShadowWidth; private int mDragShadowHeight; - private final int DRAG_SHADOW_ALPHA = 180; - private final Paint mPaint = new Paint(); + private final float DRAG_SHADOW_ALPHA = 0.7f; /** * {@link #mTopScrollBound} and {@link mBottomScrollBound} will be @@ -99,6 +103,28 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba } }; + private final AnimatorListenerAdapter mDragShadowOverAnimatorListener = + new AnimatorListenerAdapter() { + private void recycleDragShadow() { + if (mDragShadowBitmap != null) { + mDragShadowBitmap.recycle(); + mDragShadowBitmap = null; + } + mDragShadowOverlay.setVisibility(GONE); + mDragShadowOverlay.setImageBitmap(null); + } + + @Override + public void onAnimationCancel(Animator animation) { + recycleDragShadow(); + } + + @Override + public void onAnimationEnd(Animator animation) { + recycleDragShadow(); + } + }; + public PhoneFavoriteListView(Context context) { this(context, null); } @@ -109,12 +135,12 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba public PhoneFavoriteListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + mAnimationDuration = context.getResources().getInteger(R.integer.fade_duration); mDensityScale = getResources().getDisplayMetrics().density; mTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this, mDensityScale, mTouchSlop); setItemsCanFocus(true); - mPaint.setAlpha(DRAG_SHADOW_ALPHA); } @Override @@ -251,7 +277,9 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba ensureScrollHandler(); mScrollHandler.removeCallbacks(mDragScroller); mIsDragScrollerRunning = false; - if (action != DragEvent.ACTION_DRAG_EXITED) { + // Either it's been a successful drop or it's ended with out drop. + if (action == DragEvent.ACTION_DROP || + (action == DragEvent.ACTION_DRAG_ENDED && !event.getResult())) { handleDragFinished(eX, eY); } break; @@ -262,13 +290,8 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba return true; } - @Override - public void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - // Draw the drag shadow at its last known location if the drag shadow exists. - if (mDragShadowBitmap != null) { - canvas.drawBitmap(mDragShadowBitmap, mDragShadowLeft, mDragShadowTop, mPaint); - } + public void setDragShadowOverlay(ImageView overlay) { + mDragShadowOverlay = overlay; } /** @@ -292,6 +315,14 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba } } + private FrameLayout.LayoutParams getDragShadowLayoutParams() { + final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( + mDragShadowWidth, mDragShadowHeight); + lp.leftMargin = mDragShadowLeft; + lp.topMargin = mDragShadowTop; + return lp; + } + /** * @return True if the drag is started. */ @@ -307,6 +338,11 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba if (itemIndex != -1 && mOnDragDropListener != null) { final PhoneFavoriteTileView tileView = (PhoneFavoriteTileView) tile.getViewAtPosition(x, y); + if (mDragShadowOverlay == null) { + return false; + } + + mDragShadowOverlay.clearAnimation(); mDragShadowBitmap = createDraggedChildBitmap(tileView); if (mDragShadowBitmap == null) { return false; @@ -321,9 +357,16 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba mDragShadowLeft = tileView.getLeft() + tileView.getParentRow().getLeft(); mDragShadowTop = tileView.getTop() + tileView.getParentRow().getTop(); } + mDragShadowWidth = tileView.getWidth(); mDragShadowHeight = tileView.getHeight(); + mDragShadowOverlay.setImageBitmap(mDragShadowBitmap); + mDragShadowOverlay.setVisibility(VISIBLE); + mDragShadowOverlay.setAlpha(DRAG_SHADOW_ALPHA); + + mDragShadowOverlay.setLayoutParams(getDragShadowLayoutParams()); + // x and y passed in are the coordinates of where the user has touched down, calculate // the offset to the top left coordinate of the dragged child. This will be used for // drawing the drag shadow. @@ -350,8 +393,10 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba mDragShadowLeft = x - mTouchOffsetToChildLeft; mDragShadowTop = y - mTouchOffsetToChildTop; - // invalidate to trigger a redraw of the drag shadow. - invalidate(); + // Draw the drag shadow at its last known location if the drag shadow exists. + if (mDragShadowOverlay != null) { + mDragShadowOverlay.setLayoutParams(getDragShadowLayoutParams()); + } final ContactTileRow tile = (ContactTileRow) child; final int itemIndex = tile.getItemIndex(x, y); @@ -365,9 +410,12 @@ public class PhoneFavoriteListView extends ListView implements SwipeHelperCallba mDragShadowLeft = x - mTouchOffsetToChildLeft; mDragShadowTop = y - mTouchOffsetToChildTop; - if (mDragShadowBitmap != null) { - mDragShadowBitmap.recycle(); - mDragShadowBitmap = null; + if (mDragShadowOverlay != null) { + mDragShadowOverlay.clearAnimation(); + mDragShadowOverlay.animate().alpha(0.0f) + .setDuration(mAnimationDuration) + .setListener(mDragShadowOverAnimatorListener) + .start(); } if (mOnDragDropListener != null) { diff --git a/src/com/android/dialer/list/PhoneFavoriteTileView.java b/src/com/android/dialer/list/PhoneFavoriteTileView.java index 5a3f4e54d..57d258f88 100644 --- a/src/com/android/dialer/list/PhoneFavoriteTileView.java +++ b/src/com/android/dialer/list/PhoneFavoriteTileView.java @@ -31,6 +31,7 @@ import android.view.View; import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.list.ContactEntry; import com.android.contacts.common.list.ContactTileView; +import com.android.dialer.R; import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow; import com.android.dialer.list.PhoneFavoritesTileAdapter.ViewTypes; @@ -47,7 +48,7 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { private static final boolean DEBUG = false; /** Length of all animations in miniseconds. */ - private static final int ANIMATION_LENGTH = 300; + private int mAnimationDuration; /** The view that holds the front layer of the favorite contact card. */ private View mFavoriteContactCard; @@ -66,6 +67,7 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { public PhoneFavoriteTileView(Context context, AttributeSet attrs) { super(context, attrs); + mAnimationDuration = context.getResources().getInteger(R.integer.fade_duration); } public ContactTileRow getParentRow() { @@ -131,7 +133,7 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { mRemovalDialogue.setVisibility(VISIBLE); mRemovalDialogue.setAlpha(0f); final ObjectAnimator fadeIn = ObjectAnimator.ofFloat(mRemovalDialogue, "alpha", - 1.f).setDuration(ANIMATION_LENGTH); + 1.f).setDuration(mAnimationDuration); fadeIn.addListener(new AnimatorListenerAdapter() { @Override @@ -157,9 +159,9 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { // Animates back the favorite contact card. final ObjectAnimator fadeIn = ObjectAnimator.ofFloat(mFavoriteContactCard, "alpha", 1.f). - setDuration(ANIMATION_LENGTH); + setDuration(mAnimationDuration); final ObjectAnimator moveBack = ObjectAnimator.ofFloat(mFavoriteContactCard, "translationX", - 0.f).setDuration(ANIMATION_LENGTH); + 0.f).setDuration(mAnimationDuration); final AnimatorSet animSet = new AnimatorSet(); diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java index 779b15dc4..73d3c36ff 100644 --- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java +++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java @@ -609,7 +609,8 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements public void handleDrop() { boolean changed = false; if (mDraggedEntry != null) { - if (isIndexInBound(mDragEnteredEntryIndex)) { + if (isIndexInBound(mDragEnteredEntryIndex) && + mDragEnteredEntryIndex != mDraggedEntryIndex) { // Don't add the ContactEntry here (to prevent a double animation from occuring). // When we receive a new cursor the list of contact entries will automatically be // populated with the dragged ContactEntry at the correct spot. @@ -634,7 +635,6 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements PinnedPositions.STAR_WHEN_PINNING, "true").build(); // update the database here with the new pinned positions mContext.getContentResolver().update(pinUri, cv, null, null); - notifyDataSetChanged(); } mDraggedEntry = null; } |