SwipeableListView.java revision 1ef988f0c8be136fda75ed207c222413db1d3f0c
1f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira/* 2f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * Copyright (C) 2012 Google Inc. 3f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * Licensed to The Android Open Source Project. 4f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * 5f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License"); 6f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * you may not use this file except in compliance with the License. 7f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * You may obtain a copy of the License at 8f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * 9f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 10f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * 11f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * Unless required by applicable law or agreed to in writing, software 12f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 13f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * See the License for the specific language governing permissions and 15f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira * limitations under the License. 16f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira */ 17f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 18f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereirapackage com.android.mail.ui; 19f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 2007118a01f7183645957010779222b84930f75b4eMindy Pereiraimport android.animation.Animator; 2107118a01f7183645957010779222b84930f75b4eMindy Pereiraimport android.animation.AnimatorListenerAdapter; 22f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport android.content.Context; 23f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereiraimport android.content.res.Configuration; 248db7e407109532557718c6b8064792f2df7a073dMindy Pereiraimport android.net.Uri; 25f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport android.util.AttributeSet; 26f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport android.view.MotionEvent; 27f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport android.view.View; 28f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereiraimport android.view.ViewConfiguration; 29f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport android.widget.ListView; 30f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 31f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.R; 32bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport com.android.mail.browse.ConversationCursor; 33f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.browse.ConversationItemView; 341ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereiraimport com.android.mail.browse.SwipeableConversationItemView; 35f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.providers.Conversation; 3606642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereiraimport com.android.mail.providers.Folder; 37f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.ui.SwipeHelper.Callback; 38b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag; 39f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 40866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereiraimport java.util.ArrayList; 41f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport java.util.Collection; 428db7e407109532557718c6b8064792f2df7a073dMindy Pereiraimport java.util.HashMap; 43f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 448937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereirapublic class SwipeableListView extends ListView implements Callback { 45f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira private SwipeHelper mSwipeHelper; 46ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira private boolean mEnableSwipe = false; 47489dd22c64c718b6953b4bd6acef925e82c53c87Andy Huang 48b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook public static final String LOG_TAG = LogTag.getLogTag(); 49f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 50866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira private ConversationSelectionSet mConvSelectionSet; 516c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira private int mSwipeAction; 5206642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira private Folder mFolder; 53866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 54f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context) { 55f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira this(context, null); 56f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 57f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 58f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context, AttributeSet attrs) { 59f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira this(context, attrs, -1); 60f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 61f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 62f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context, AttributeSet attrs, int defStyle) { 63f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira super(context, attrs, defStyle); 64f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira float densityScale = getResources().getDisplayMetrics().density; 65f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float pagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); 66866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira float scrollSlop = context.getResources().getInteger(R.integer.swipeScrollSlop); 67cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira float minSwipe = context.getResources().getDimension(R.dimen.min_swipe); 68cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira float minVert = context.getResources().getDimension(R.dimen.min_vert); 69cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira float minLock = context.getResources().getDimension(R.dimen.min_lock); 70f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop, 71cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira scrollSlop, minSwipe, minVert, minLock); 72f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 73f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 74f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira @Override 75f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira protected void onConfigurationChanged(Configuration newConfig) { 76f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira super.onConfigurationChanged(newConfig); 77f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float densityScale = getResources().getDisplayMetrics().density; 78f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper.setDensityScale(densityScale); 79f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop(); 80f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper.setPagingTouchSlop(pagingTouchSlop); 81f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira } 82f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira 83ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira /** 84ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira * Enable swipe gestures. 85ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira */ 86ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira public void enableSwipe(boolean enable) { 87ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira mEnableSwipe = enable; 88ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira } 89ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira 90f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira public boolean isSwipeEnabled() { 91f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira return mEnableSwipe; 92f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira } 93f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira 946c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void setSwipeAction(int action) { 956c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira mSwipeAction = action; 96f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 97f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 98de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira public int getSwipeAction() { 99de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira return mSwipeAction; 100de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira } 101de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira 102866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public void setSelectionSet(ConversationSelectionSet set) { 103866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mConvSelectionSet = set; 104866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 105866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 10606642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira public void setCurrentFolder(Folder folder) { 10706642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira mFolder = folder; 10806642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira } 10906642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira 110866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira @Override 111866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public ConversationSelectionSet getSelectionSet() { 112866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira return mConvSelectionSet; 113866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 114866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 115f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 116f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public boolean onInterceptTouchEvent(MotionEvent ev) { 117ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira if (mEnableSwipe) { 11819bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return mSwipeHelper.onInterceptTouchEvent(ev) 11919bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira || super.onInterceptTouchEvent(ev); 12019bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } else { 12119bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return super.onInterceptTouchEvent(ev); 12219bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } 123f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 124f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 125f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 126f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public boolean onTouchEvent(MotionEvent ev) { 127ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira if (mEnableSwipe) { 12819bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev); 12919bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } else { 13019bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return super.onTouchEvent(ev); 13119bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } 132f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 133f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 134f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 135f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public View getChildAtPosition(MotionEvent ev) { 136f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira // find the view under the pointer, accounting for GONE views 137f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira final int count = getChildCount(); 138f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira int touchY = (int) ev.getY(); 139f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira int childIdx = 0; 140f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira View slidingChild; 141f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira for (; childIdx < count; childIdx++) { 142f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira slidingChild = getChildAt(childIdx); 143f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira if (slidingChild.getVisibility() == GONE) { 144f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira continue; 145f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 146866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira if (touchY >= slidingChild.getTop() && touchY <= slidingChild.getBottom()) { 1471ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira if (slidingChild instanceof SwipeableConversationItemView) { 1481ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira return ((SwipeableConversationItemView) slidingChild).getSwipeableItemView(); 1491ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira } 150866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira return slidingChild; 151866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 152f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 153f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira return null; 154f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 155f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 156f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 1576c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public boolean canChildBeDismissed(SwipeableItemView v) { 1586c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira View view = v.getView(); 1596c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira return view instanceof ConversationItemView || view instanceof LeaveBehindItem; 160f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 161f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 162f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 1636c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onChildDismissed(SwipeableItemView v) { 1646c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira View view = v.getView(); 1656c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira if (view instanceof ConversationItemView) { 1666c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira dismissChildren((ConversationItemView) v, null); 1676c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } else if (view instanceof LeaveBehindItem) { 1686c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira ((LeaveBehindItem)view).commit(); 1696c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 170f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 171f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 1728937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // Call this whenever a new action is taken; this forces a commit of any 1738937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // existing destructive actions. 1748937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira public void commitDestructiveActions() { 1750fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 1768937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira if (adapter != null) { 1778937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira adapter.commitLeaveBehindItems(); 1788937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 1798937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 1808937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira 181f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 1826c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onChildrenDismissed(SwipeableItemView target, 1836c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira Collection<ConversationItemView> views) { 1846c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira assert(target instanceof ConversationItemView); 1856c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira dismissChildren((ConversationItemView) target.getView(), views); 186866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 187866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 1886c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira private void dismissChildren(final ConversationItemView target, 1896c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira final Collection<ConversationItemView> conversationViews) { 1906c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira final Context context = getContext(); 1910fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 192d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira final ToastBarOperation undoOp; 1936c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira if (conversationViews != null) { 1946c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira final ArrayList<Conversation> conversations = new ArrayList<Conversation>( 1956c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira conversationViews.size()); 19606642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira Conversation conversation; 1976c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira for (ConversationItemView view : conversationViews) { 1986c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira if (view.getConversation().id != target.getConversation().id) { 19906642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira conversation = view.getConversation(); 20006642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira conversation.localDeleteOnUpdate = true; 20106642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira conversations.add(conversation); 2026c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2036c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 204d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira undoOp = new ToastBarOperation(conversationViews != null ? 205d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira (conversations.size() + 1) : 1, mSwipeAction, ToastBarOperation.UNDO); 2066c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira handleLeaveBehind(target, undoOp, context); 20709a4bfe3f81ee216b5c4a4e2d083432a4e387abdVikram Aggarwal adapter.delete(conversations, new DestructiveAction() { 208bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook @Override 20909a4bfe3f81ee216b5c4a4e2d083432a4e387abdVikram Aggarwal public void performAction() { 2108db7e407109532557718c6b8064792f2df7a073dMindy Pereira ConversationCursor cc = (ConversationCursor) adapter.getCursor(); 2116c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira switch (mSwipeAction) { 2126c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.archive: 213bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook cc.archive(context, conversations); 2146c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 21506642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira case R.id.change_folder: 2168db7e407109532557718c6b8064792f2df7a073dMindy Pereira FolderOperation folderOp = new FolderOperation(mFolder, false); 2178db7e407109532557718c6b8064792f2df7a073dMindy Pereira // For each conversation, for each operation, remove 2188db7e407109532557718c6b8064792f2df7a073dMindy Pereira // the current folder. 2198db7e407109532557718c6b8064792f2df7a073dMindy Pereira for (Conversation target : conversations) { 2208db7e407109532557718c6b8064792f2df7a073dMindy Pereira HashMap<Uri, Folder> targetFolders = Folder 2218db7e407109532557718c6b8064792f2df7a073dMindy Pereira .hashMapForFoldersString(target.rawFolders); 2228db7e407109532557718c6b8064792f2df7a073dMindy Pereira targetFolders.remove(folderOp.mFolder.uri); 2238db7e407109532557718c6b8064792f2df7a073dMindy Pereira target.folderList = Folder.getUriString(targetFolders.values()); 2248db7e407109532557718c6b8064792f2df7a073dMindy Pereira target.rawFolders = Folder.getSerializedFolderString(mFolder, 2258db7e407109532557718c6b8064792f2df7a073dMindy Pereira targetFolders.values()); 2268db7e407109532557718c6b8064792f2df7a073dMindy Pereira cc.updateStrings(context, Conversation.listOf(target), 2278db7e407109532557718c6b8064792f2df7a073dMindy Pereira Conversation.UPDATE_FOLDER_COLUMNS, new String[] { 2288db7e407109532557718c6b8064792f2df7a073dMindy Pereira target.folderList, target.rawFolders 2298db7e407109532557718c6b8064792f2df7a073dMindy Pereira }); 2308db7e407109532557718c6b8064792f2df7a073dMindy Pereira } 23106642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira break; 2326c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.delete: 233bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook cc.delete(context, conversations); 2346c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 2356c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2366c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2376c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira }); 2386c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } else { 239d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira undoOp = new ToastBarOperation(1, mSwipeAction, ToastBarOperation.UNDO); 2404cda97978c9f2c4b7e4a645268040223b8dbc83eMindy Pereira target.getConversation().position = target.getParent() != null ? 2414cda97978c9f2c4b7e4a645268040223b8dbc83eMindy Pereira getPositionForView(target) : -1; 2426c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira handleLeaveBehind(target, undoOp, context); 243f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 244866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 245866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 246d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira private void handleLeaveBehind(ConversationItemView target, ToastBarOperation undoOp, 2476c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira Context context) { 2486c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira Conversation conv = target.getConversation(); 2490fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 25009f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira if (adapter == null) { 25109f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira return; 25209f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira } 2536c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira adapter.setupLeaveBehind(conv, undoOp, conv.position); 254bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook ConversationCursor cc = (ConversationCursor)adapter.getCursor(); 2556c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira switch (mSwipeAction) { 25606642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira case R.id.change_folder: 2578db7e407109532557718c6b8064792f2df7a073dMindy Pereira FolderOperation folderOp = new FolderOperation(mFolder, false); 2588db7e407109532557718c6b8064792f2df7a073dMindy Pereira HashMap<Uri, Folder> targetFolders = Folder 2598db7e407109532557718c6b8064792f2df7a073dMindy Pereira .hashMapForFoldersString(conv.rawFolders); 2608db7e407109532557718c6b8064792f2df7a073dMindy Pereira targetFolders.remove(folderOp.mFolder.uri); 2618db7e407109532557718c6b8064792f2df7a073dMindy Pereira conv.folderList = Folder.getUriString(targetFolders.values()); 2628db7e407109532557718c6b8064792f2df7a073dMindy Pereira conv.rawFolders = Folder.getSerializedFolderString(mFolder, targetFolders.values()); 2638db7e407109532557718c6b8064792f2df7a073dMindy Pereira cc.mostlyDestructiveUpdate(context, Conversation.listOf(conv), 2648db7e407109532557718c6b8064792f2df7a073dMindy Pereira Conversation.UPDATE_FOLDER_COLUMNS, new String[] { 2658db7e407109532557718c6b8064792f2df7a073dMindy Pereira conv.folderList, conv.rawFolders 266ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira }); 26706642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira break; 2686c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.archive: 269a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira cc.mostlyArchive(context, Conversation.listOf(conv)); 2706c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 2716c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.delete: 272a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira cc.mostlyDelete(context, Conversation.listOf(conv)); 2736c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 2746c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2756c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira adapter.notifyDataSetChanged(); 276a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira if (mConvSelectionSet != null && !mConvSelectionSet.isEmpty() 277a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira && mConvSelectionSet.contains(conv)) { 278a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira mConvSelectionSet.toggle(null, conv); 279cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira } 280f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 281f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 282f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 283f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public void onBeginDrag(View v) { 284f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira // We do this so the underlying ScrollView knows that it won't get 285f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira // the chance to intercept events anymore 286f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira requestDisallowInterceptTouchEvent(true); 2871ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira SwipeableConversationItemView view = null; 2881ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira if (v instanceof ConversationItemView) { 2891ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira view = (SwipeableConversationItemView)v.getParent(); 2901ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira } 2911ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira if (view != null) { 2921ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira view.addBackground(getContext(), getSwipeActionText()); 2931ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira view.setBackgroundVisibility(View.VISIBLE); 2941ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira } 295f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 296f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 297f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 2986c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onDragCancelled(SwipeableItemView v) { 299f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 300f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 30107118a01f7183645957010779222b84930f75b4eMindy Pereira /** 30207118a01f7183645957010779222b84930f75b4eMindy Pereira * Archive items using the swipe away animation before shrinking them away. 30307118a01f7183645957010779222b84930f75b4eMindy Pereira */ 304de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira public void destroyItems(ArrayList<ConversationItemView> views, 30509a4bfe3f81ee216b5c4a4e2d083432a4e387abdVikram Aggarwal final DestructiveAction listener) { 30607118a01f7183645957010779222b84930f75b4eMindy Pereira if (views == null || views.size() == 0) { 30707118a01f7183645957010779222b84930f75b4eMindy Pereira return; 30807118a01f7183645957010779222b84930f75b4eMindy Pereira } 30907118a01f7183645957010779222b84930f75b4eMindy Pereira final ArrayList<Conversation> conversations = new ArrayList<Conversation>(); 31007118a01f7183645957010779222b84930f75b4eMindy Pereira for (ConversationItemView view : views) { 311de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira Conversation conv = view.getConversation(); 312de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira conv.position = view.getParent() != null ? getPositionForView(view) : -1; 313de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira conversations.add(conv); 31407118a01f7183645957010779222b84930f75b4eMindy Pereira } 31507118a01f7183645957010779222b84930f75b4eMindy Pereira mSwipeHelper.dismissChildren(views.get(0), views, new AnimatorListenerAdapter() { 31607118a01f7183645957010779222b84930f75b4eMindy Pereira @Override 31707118a01f7183645957010779222b84930f75b4eMindy Pereira public void onAnimationEnd(Animator animation) { 3180fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira AnimatedAdapter adapter = getAnimatedAdapter(); 3190fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira if (adapter != null) { 3200fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira adapter.delete(conversations, listener); 3210fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira } 32207118a01f7183645957010779222b84930f75b4eMindy Pereira } 32307118a01f7183645957010779222b84930f75b4eMindy Pereira }); 32407118a01f7183645957010779222b84930f75b4eMindy Pereira } 32507118a01f7183645957010779222b84930f75b4eMindy Pereira 3260fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira private AnimatedAdapter getAnimatedAdapter() { 3270fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira return (AnimatedAdapter) getAdapter(); 3280fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira } 3290fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira 330f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public interface SwipeCompleteListener { 331f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public void onSwipeComplete(Collection<Conversation> conversations); 332f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 3338937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira 3348937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira @Override 3358937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira public boolean performItemClick(View view, int pos, long id) { 3368937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // Commit any existing destructive actions when the user selects a conversation to view. 3378937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira commitDestructiveActions(); 3388937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira return super.performItemClick(view, pos, id); 3398937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 3401ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira 3411ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira /** 3421ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira * Get the text resource corresponding to the result of a swipe. 3431ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira */ 3441ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira public int getSwipeActionText() { 3451ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira switch (mSwipeAction) { 3461ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira case R.id.archive: 3471ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira return R.string.archive; 3481ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira case R.id.delete: 3491ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira return R.string.delete; 3501ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira case R.id.change_folder: 3511ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira return R.string.remove_label; 3521ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira } 3531ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira return -1; 3541ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira } 3556c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira}