diff options
author | Andy Huang <ath@google.com> | 2012-07-24 18:50:34 -0700 |
---|---|---|
committer | Mindy Pereira <mindyp@google.com> | 2012-07-25 11:38:10 -0700 |
commit | 62d7962b2b4d73f8414bbab1f42952442ac25be0 (patch) | |
tree | faa81f3e7d690a59cfc60f35c44f9632e5665fb2 /src/com/android | |
parent | c11011d29d87f76d902438b2f79c75d1ebc45fda (diff) | |
download | android_packages_apps_UnifiedEmail-62d7962b2b4d73f8414bbab1f42952442ac25be0.tar.gz android_packages_apps_UnifiedEmail-62d7962b2b4d73f8414bbab1f42952442ac25be0.tar.bz2 android_packages_apps_UnifiedEmail-62d7962b2b4d73f8414bbab1f42952442ac25be0.zip |
Animate out existing leave behinds.
When the user swipes away a new item and there is a leave behind showing,
shrink away the existing leave behind so that we maintain some reasonable positioning.
Change-Id: I7318cc6ad1a7c0c8ed3420374680bac549c2e458
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/mail/browse/SwipeableConversationItemView.java | 9 | ||||
-rw-r--r-- | src/com/android/mail/ui/AnimatedAdapter.java | 77 | ||||
-rw-r--r-- | src/com/android/mail/ui/AnimatingItemView.java | 20 | ||||
-rw-r--r-- | src/com/android/mail/ui/LeaveBehindItem.java | 17 |
4 files changed, 103 insertions, 20 deletions
diff --git a/src/com/android/mail/browse/SwipeableConversationItemView.java b/src/com/android/mail/browse/SwipeableConversationItemView.java index c7594c9d9..66229d001 100644 --- a/src/com/android/mail/browse/SwipeableConversationItemView.java +++ b/src/com/android/mail/browse/SwipeableConversationItemView.java @@ -44,10 +44,13 @@ public class SwipeableConversationItemView extends FrameLayout { } public void addBackground(Context context, int textRes) { - mBackground = (TextView) LayoutInflater.from(context).inflate(R.layout.background, null, - true); + mBackground = (TextView) findViewById(R.id.background); + if (mBackground == null) { + mBackground = (TextView) LayoutInflater.from(context).inflate(R.layout.background, + null, true); + addView(mBackground, 0); + } mBackground.setText(textRes); - addView(mBackground, 0); } public void setBackgroundVisibility(int visibility) { diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java index 80a9e95e3..699124620 100644 --- a/src/com/android/mail/ui/AnimatedAdapter.java +++ b/src/com/android/mail/ui/AnimatedAdapter.java @@ -82,6 +82,8 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements private Settings mCachedSettings; private boolean mSwipeEnabled; private HashMap<Long, LeaveBehindItem> mLeaveBehindItems = new HashMap<Long, LeaveBehindItem>(); + private HashMap<Long, LeaveBehindItem> mFadeLeaveBehindItems = + new HashMap<Long, LeaveBehindItem>(); /** * Used only for debugging. @@ -163,7 +165,7 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements if (mShowFooter && position == super.getCount()) { return TYPE_VIEW_FOOTER; } - if (isPositionLeaveBehind(position)) { + if (isPositionLeaveBehind(position) || isPositionFadeLeaveBehind(position)) { return TYPE_VIEW_LEAVEBEHIND; } return TYPE_VIEW_CONVERSATION; @@ -235,6 +237,14 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements } else if (isPositionDeleting(position)) { return getDeletingView(position, convertView, parent); } + if (hasFadeLeaveBehinds()) { + Conversation conv = new Conversation((ConversationCursor) getItem(position)); + if(isPositionFadeLeaveBehind(conv)) { + LeaveBehindItem fade = getFadeLeaveBehindItem(position, conv); + fade.startAnimation(mViewMode, this); + return fade; + } + } if (hasLeaveBehinds()) { Conversation conv = new Conversation((ConversationCursor) getItem(position)); if(isPositionLeaveBehind(conv)) { @@ -262,8 +272,12 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements return !mLeaveBehindItems.isEmpty(); } + private boolean hasFadeLeaveBehinds() { + return !mFadeLeaveBehindItems.isEmpty(); + } + public void setupLeaveBehind(Conversation target, ToastBarOperation undoOp, int deletedRow) { - commitLeaveBehindItems(); + fadeOutLeaveBehindItems(); LeaveBehindItem leaveBehind = (LeaveBehindItem) LayoutInflater.from(mContext).inflate( R.layout.swipe_leavebehind, null); leaveBehind.bindOperations(mSelectedAccount, this, undoOp, @@ -272,13 +286,39 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements mLastDeletingItems.add(deletedRow); } + public void fadeOutLeaveBehindItems() { + // Remove any previously existing leave behinds. + final int startPosition = mListView.getFirstVisiblePosition(); + final int endPosition = mListView.getLastVisiblePosition(); + + if (!mLeaveBehindItems.isEmpty()) { + for (Long id : mLeaveBehindItems.keySet()) { + // If the item is visible, fade it out. Otherwise, just remove + // it. + Conversation conv = mLeaveBehindItems.get(id).getData(); + if (conv.position >= startPosition && conv.position <= endPosition) { + mFadeLeaveBehindItems.put(id, mLeaveBehindItems.get(id)); + } + } + mLeaveBehindItems.clear(); + } + if (!mLastDeletingItems.isEmpty()) { + mLastDeletingItems.clear(); + } + notifyDataSetChanged(); + } + public void commitLeaveBehindItems() { // Remove any previously existing leave behinds. if (!mLeaveBehindItems.isEmpty()) { for (LeaveBehindItem item : mLeaveBehindItems.values()) { item.commit(); } + for (LeaveBehindItem item : mFadeLeaveBehindItems.values()) { + item.commit(); + } mLeaveBehindItems.clear(); + mFadeLeaveBehindItems.clear(); } if (!mLastDeletingItems.isEmpty()) { mLastDeletingItems.clear(); @@ -290,6 +330,10 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements return mLeaveBehindItems.get(target.id); } + private LeaveBehindItem getFadeLeaveBehindItem(int position, Conversation target) { + return mFadeLeaveBehindItems.get(target.id); + } + @Override public long getItemId(int position) { if (mShowFooter && position == super.getCount()) { @@ -316,7 +360,8 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements conversation.position = position; // Destroying a conversation just shows a blank shrinking item. final AnimatingItemView view = new AnimatingItemView(mContext); - view.startAnimation(conversation, mViewMode, this); + view.setData(conversation); + view.startAnimation(mViewMode, this); return view; } @@ -355,12 +400,25 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements return mLeaveBehindItems.containsKey(conv.id) && conv.isMostlyDead(); } + private boolean isPositionFadeLeaveBehind(Conversation conv) { + return mFadeLeaveBehindItems.containsKey(conv.id) && conv.isMostlyDead(); + } + private boolean isPositionLeaveBehind(int position) { if (hasLeaveBehinds()) { Object item = getItem(position); if (item instanceof ConversationCursor) { - Conversation conv = new Conversation((ConversationCursor) item); - return mLeaveBehindItems.containsKey(conv.id) && conv.isMostlyDead(); + return isPositionLeaveBehind(new Conversation((ConversationCursor) item)); + } + } + return false; + } + + private boolean isPositionFadeLeaveBehind(int position) { + if (hasFadeLeaveBehinds()) { + Object item = getItem(position); + if (item instanceof ConversationCursor) { + return isPositionFadeLeaveBehind(new Conversation((ConversationCursor) item)); } } return false; @@ -390,7 +448,14 @@ public class AnimatedAdapter extends SimpleCursorAdapter implements @Override public void onAnimationEnd(Animator animation) { - if (!mUndoingItems.isEmpty()) { + if (hasFadeLeaveBehinds()) { + Object obj = ((ObjectAnimator) animation).getTarget(); + if (obj instanceof LeaveBehindItem) { + LeaveBehindItem objItem = (LeaveBehindItem)obj; + mFadeLeaveBehindItems.remove(objItem.getConversationId()); + objItem.commit(); + } + } else if (!mUndoingItems.isEmpty()) { // See if we have received all the animations we expected; if // so, call the listener and reset it. final int position = ((ConversationItemView) ((ObjectAnimator) animation).getTarget()) diff --git a/src/com/android/mail/ui/AnimatingItemView.java b/src/com/android/mail/ui/AnimatingItemView.java index 13371a958..0d323388e 100644 --- a/src/com/android/mail/ui/AnimatingItemView.java +++ b/src/com/android/mail/ui/AnimatingItemView.java @@ -20,6 +20,7 @@ package com.android.mail.ui; import android.animation.Animator.AnimatorListener; import android.animation.ObjectAnimator; import android.content.Context; +import android.util.AttributeSet; import android.view.animation.DecelerateInterpolator; import android.widget.LinearLayout; @@ -31,9 +32,13 @@ public class AnimatingItemView extends LinearLayout { super(context); } + public AnimatingItemView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + private Conversation mData; private ObjectAnimator mAnimator; - private int mAnimatedHeight; + private int mAnimatedHeight = -1; /** * Start the animation on an animating view. @@ -42,8 +47,7 @@ public class AnimatingItemView extends LinearLayout { * @param undo true if an operation is being undone. We animate the item away during delete. * Undoing populates the item. */ - public void startAnimation(Conversation item, ViewMode viewMode, AnimatorListener listener) { - mData = item; + public void startAnimation(ViewMode viewMode, AnimatorListener listener) { int minHeight = ConversationItemViewCoordinates.getMinHeight(getContext(), viewMode); setMinimumHeight(minHeight); final int start = minHeight; @@ -57,13 +61,21 @@ public class AnimatingItemView extends LinearLayout { mAnimator.start(); } + public void setData(Conversation conversation) { + mData = conversation; + } + public Conversation getData() { return mData; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mAnimatedHeight); + if (mAnimatedHeight != -1) { + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mAnimatedHeight); + } else { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } return; } diff --git a/src/com/android/mail/ui/LeaveBehindItem.java b/src/com/android/mail/ui/LeaveBehindItem.java index 51c1c997c..3482183a1 100644 --- a/src/com/android/mail/ui/LeaveBehindItem.java +++ b/src/com/android/mail/ui/LeaveBehindItem.java @@ -22,7 +22,6 @@ import android.text.Html; import android.util.AttributeSet; import android.view.View; import android.view.View.OnClickListener; -import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; @@ -32,13 +31,12 @@ import com.android.mail.providers.Account; import com.android.mail.providers.Conversation; import com.google.common.collect.ImmutableList; -public class LeaveBehindItem extends LinearLayout implements OnClickListener, +public class LeaveBehindItem extends AnimatingItemView implements OnClickListener, SwipeableItemView { private ToastBarOperation mUndoOp; private Account mAccount; private AnimatedAdapter mAdapter; - private Conversation mConversation; private ConversationCursor mConversationCursor; public LeaveBehindItem(Context context) { @@ -65,7 +63,7 @@ public class LeaveBehindItem extends LinearLayout implements OnClickListener, // TODO: Use UIProvider.SEQUENCE_QUERY_PARAMETER to indicate // the set of // commands to undo - mAdapter.clearLeaveBehind(mConversation); + mAdapter.clearLeaveBehind(getData()); mAdapter.setUndo(true); mConversationCursor.undo(getContext(), mAccount.undoUri); } @@ -79,15 +77,20 @@ public class LeaveBehindItem extends LinearLayout implements OnClickListener, mAccount = account; mAdapter = adapter; mConversationCursor = (ConversationCursor)adapter.getCursor(); - mConversation = target; + setData(target); ((TextView) findViewById(R.id.undo_descriptionview)).setText(Html.fromHtml(mUndoOp .getDescription(getContext()))); ((RelativeLayout) findViewById(R.id.undo_button)).setOnClickListener(this); } public void commit() { - mConversationCursor.delete(getContext(), ImmutableList.of(mConversation)); - mAdapter.clearLeaveBehind(mConversation); + Conversation conv = getData(); + mConversationCursor.delete(getContext(), ImmutableList.of(conv)); + mAdapter.clearLeaveBehind(conv); + } + + public long getConversationId() { + return getData().id; } @Override |