summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorAndy Huang <ath@google.com>2012-07-24 18:50:34 -0700
committerMindy Pereira <mindyp@google.com>2012-07-25 11:38:10 -0700
commit62d7962b2b4d73f8414bbab1f42952442ac25be0 (patch)
treefaa81f3e7d690a59cfc60f35c44f9632e5665fb2 /src/com/android
parentc11011d29d87f76d902438b2f79c75d1ebc45fda (diff)
downloadandroid_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.java9
-rw-r--r--src/com/android/mail/ui/AnimatedAdapter.java77
-rw-r--r--src/com/android/mail/ui/AnimatingItemView.java20
-rw-r--r--src/com/android/mail/ui/LeaveBehindItem.java17
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