SwipeableListView.java revision de3e74a82043733243c7391d7f983a5af8842891
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; 34f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.providers.Conversation; 3506642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereiraimport com.android.mail.providers.Folder; 36f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.ui.SwipeHelper.Callback; 37b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag; 38f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 39866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereiraimport java.util.ArrayList; 40f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport java.util.Collection; 418db7e407109532557718c6b8064792f2df7a073dMindy Pereiraimport java.util.HashMap; 42f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 438937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereirapublic class SwipeableListView extends ListView implements Callback { 44f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira private SwipeHelper mSwipeHelper; 45ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira private boolean mEnableSwipe = false; 46489dd22c64c718b6953b4bd6acef925e82c53c87Andy Huang 47b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook public static final String LOG_TAG = LogTag.getLogTag(); 48f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 49866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira private ConversationSelectionSet mConvSelectionSet; 506c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira private int mSwipeAction; 5106642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira private Folder mFolder; 52866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 53f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context) { 54f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira this(context, null); 55f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 56f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 57f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context, AttributeSet attrs) { 58f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira this(context, attrs, -1); 59f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 60f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 61f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context, AttributeSet attrs, int defStyle) { 62f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira super(context, attrs, defStyle); 63f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira float densityScale = getResources().getDisplayMetrics().density; 64f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float pagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); 65866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira float scrollSlop = context.getResources().getInteger(R.integer.swipeScrollSlop); 66cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira float minSwipe = context.getResources().getDimension(R.dimen.min_swipe); 67cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira float minVert = context.getResources().getDimension(R.dimen.min_vert); 68cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira float minLock = context.getResources().getDimension(R.dimen.min_lock); 69f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop, 70cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira scrollSlop, minSwipe, minVert, minLock); 71f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 72f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 73f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira @Override 74f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira protected void onConfigurationChanged(Configuration newConfig) { 75f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira super.onConfigurationChanged(newConfig); 76f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float densityScale = getResources().getDisplayMetrics().density; 77f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper.setDensityScale(densityScale); 78f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop(); 79f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper.setPagingTouchSlop(pagingTouchSlop); 80f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira } 81f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira 82ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira /** 83ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira * Enable swipe gestures. 84ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira */ 85ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira public void enableSwipe(boolean enable) { 86ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira mEnableSwipe = enable; 87ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira } 88ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira 89f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira public boolean isSwipeEnabled() { 90f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira return mEnableSwipe; 91f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira } 92f07269fdfbc0ca2607dad50bfc15c2c041c1faddMindy Pereira 936c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void setSwipeAction(int action) { 946c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira mSwipeAction = action; 95f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 96f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 97de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira public int getSwipeAction() { 98de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira return mSwipeAction; 99de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira } 100de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira 101866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public void setSelectionSet(ConversationSelectionSet set) { 102866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mConvSelectionSet = set; 103866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 104866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 10506642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira public void setCurrentFolder(Folder folder) { 10606642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira mFolder = folder; 10706642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira } 10806642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira 109866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira @Override 110866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public ConversationSelectionSet getSelectionSet() { 111866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira return mConvSelectionSet; 112866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 113866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 114f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 115f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public boolean onInterceptTouchEvent(MotionEvent ev) { 116ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira if (mEnableSwipe) { 11719bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return mSwipeHelper.onInterceptTouchEvent(ev) 11819bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira || super.onInterceptTouchEvent(ev); 11919bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } else { 12019bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return super.onInterceptTouchEvent(ev); 12119bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } 122f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 123f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 124f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 125f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public boolean onTouchEvent(MotionEvent ev) { 126ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira if (mEnableSwipe) { 12719bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev); 12819bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } else { 12919bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return super.onTouchEvent(ev); 13019bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } 131f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 132f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 133f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 134f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public View getChildAtPosition(MotionEvent ev) { 135f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira // find the view under the pointer, accounting for GONE views 136f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira final int count = getChildCount(); 137f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira int touchY = (int) ev.getY(); 138f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira int childIdx = 0; 139f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira View slidingChild; 140f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira for (; childIdx < count; childIdx++) { 141f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira slidingChild = getChildAt(childIdx); 142f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira if (slidingChild.getVisibility() == GONE) { 143f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira continue; 144f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 145866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira if (touchY >= slidingChild.getTop() && touchY <= slidingChild.getBottom()) { 146866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira return slidingChild; 147866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 148f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 149f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira return null; 150f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 151f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 152f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 1536c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public boolean canChildBeDismissed(SwipeableItemView v) { 1546c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira View view = v.getView(); 1556c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira return view instanceof ConversationItemView || view instanceof LeaveBehindItem; 156f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 157f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 158f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 1596c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onChildDismissed(SwipeableItemView v) { 1606c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira View view = v.getView(); 1616c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira if (view instanceof ConversationItemView) { 1626c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira dismissChildren((ConversationItemView) v, null); 1636c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } else if (view instanceof LeaveBehindItem) { 1646c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira ((LeaveBehindItem)view).commit(); 1656c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 166f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 167f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 1688937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // Call this whenever a new action is taken; this forces a commit of any 1698937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // existing destructive actions. 1708937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira public void commitDestructiveActions() { 1710fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 1728937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira if (adapter != null) { 1738937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira adapter.commitLeaveBehindItems(); 1748937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 1758937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 1768937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira 177f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 1786c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onChildrenDismissed(SwipeableItemView target, 1796c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira Collection<ConversationItemView> views) { 1806c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira assert(target instanceof ConversationItemView); 1816c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira dismissChildren((ConversationItemView) target.getView(), views); 182866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 183866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 1846c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira private void dismissChildren(final ConversationItemView target, 1856c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira final Collection<ConversationItemView> conversationViews) { 1866c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira final Context context = getContext(); 1870fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 188d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira final ToastBarOperation undoOp; 1896c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira if (conversationViews != null) { 1906c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira final ArrayList<Conversation> conversations = new ArrayList<Conversation>( 1916c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira conversationViews.size()); 19206642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira Conversation conversation; 1936c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira for (ConversationItemView view : conversationViews) { 1946c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira if (view.getConversation().id != target.getConversation().id) { 19506642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira conversation = view.getConversation(); 19606642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira conversation.localDeleteOnUpdate = true; 19706642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira conversations.add(conversation); 1986c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 1996c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 200d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira undoOp = new ToastBarOperation(conversationViews != null ? 201d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira (conversations.size() + 1) : 1, mSwipeAction, ToastBarOperation.UNDO); 2026c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira handleLeaveBehind(target, undoOp, context); 20309a4bfe3f81ee216b5c4a4e2d083432a4e387abdVikram Aggarwal adapter.delete(conversations, new DestructiveAction() { 204bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook @Override 20509a4bfe3f81ee216b5c4a4e2d083432a4e387abdVikram Aggarwal public void performAction() { 2068db7e407109532557718c6b8064792f2df7a073dMindy Pereira ConversationCursor cc = (ConversationCursor) adapter.getCursor(); 2076c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira switch (mSwipeAction) { 2086c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.archive: 209bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook cc.archive(context, conversations); 2106c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 21106642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira case R.id.change_folder: 2128db7e407109532557718c6b8064792f2df7a073dMindy Pereira FolderOperation folderOp = new FolderOperation(mFolder, false); 2138db7e407109532557718c6b8064792f2df7a073dMindy Pereira // For each conversation, for each operation, remove 2148db7e407109532557718c6b8064792f2df7a073dMindy Pereira // the current folder. 2158db7e407109532557718c6b8064792f2df7a073dMindy Pereira for (Conversation target : conversations) { 2168db7e407109532557718c6b8064792f2df7a073dMindy Pereira HashMap<Uri, Folder> targetFolders = Folder 2178db7e407109532557718c6b8064792f2df7a073dMindy Pereira .hashMapForFoldersString(target.rawFolders); 2188db7e407109532557718c6b8064792f2df7a073dMindy Pereira targetFolders.remove(folderOp.mFolder.uri); 2198db7e407109532557718c6b8064792f2df7a073dMindy Pereira target.folderList = Folder.getUriString(targetFolders.values()); 2208db7e407109532557718c6b8064792f2df7a073dMindy Pereira target.rawFolders = Folder.getSerializedFolderString(mFolder, 2218db7e407109532557718c6b8064792f2df7a073dMindy Pereira targetFolders.values()); 2228db7e407109532557718c6b8064792f2df7a073dMindy Pereira cc.updateStrings(context, Conversation.listOf(target), 2238db7e407109532557718c6b8064792f2df7a073dMindy Pereira Conversation.UPDATE_FOLDER_COLUMNS, new String[] { 2248db7e407109532557718c6b8064792f2df7a073dMindy Pereira target.folderList, target.rawFolders 2258db7e407109532557718c6b8064792f2df7a073dMindy Pereira }); 2268db7e407109532557718c6b8064792f2df7a073dMindy Pereira } 22706642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira break; 2286c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.delete: 229bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook cc.delete(context, conversations); 2306c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 2316c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2326c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2336c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira }); 2346c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } else { 235d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira undoOp = new ToastBarOperation(1, mSwipeAction, ToastBarOperation.UNDO); 2364cda97978c9f2c4b7e4a645268040223b8dbc83eMindy Pereira target.getConversation().position = target.getParent() != null ? 2374cda97978c9f2c4b7e4a645268040223b8dbc83eMindy Pereira getPositionForView(target) : -1; 2386c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira handleLeaveBehind(target, undoOp, context); 239f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 240866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 241866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 242d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira private void handleLeaveBehind(ConversationItemView target, ToastBarOperation undoOp, 2436c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira Context context) { 2446c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira Conversation conv = target.getConversation(); 2450fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 24609f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira if (adapter == null) { 24709f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira return; 24809f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira } 2496c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira adapter.setupLeaveBehind(conv, undoOp, conv.position); 250bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook ConversationCursor cc = (ConversationCursor)adapter.getCursor(); 2516c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira switch (mSwipeAction) { 25206642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira case R.id.change_folder: 2538db7e407109532557718c6b8064792f2df7a073dMindy Pereira FolderOperation folderOp = new FolderOperation(mFolder, false); 2548db7e407109532557718c6b8064792f2df7a073dMindy Pereira HashMap<Uri, Folder> targetFolders = Folder 2558db7e407109532557718c6b8064792f2df7a073dMindy Pereira .hashMapForFoldersString(conv.rawFolders); 2568db7e407109532557718c6b8064792f2df7a073dMindy Pereira targetFolders.remove(folderOp.mFolder.uri); 2578db7e407109532557718c6b8064792f2df7a073dMindy Pereira conv.folderList = Folder.getUriString(targetFolders.values()); 2588db7e407109532557718c6b8064792f2df7a073dMindy Pereira conv.rawFolders = Folder.getSerializedFolderString(mFolder, targetFolders.values()); 2598db7e407109532557718c6b8064792f2df7a073dMindy Pereira cc.mostlyDestructiveUpdate(context, Conversation.listOf(conv), 2608db7e407109532557718c6b8064792f2df7a073dMindy Pereira Conversation.UPDATE_FOLDER_COLUMNS, new String[] { 2618db7e407109532557718c6b8064792f2df7a073dMindy Pereira conv.folderList, conv.rawFolders 262ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira }); 26306642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira break; 2646c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.archive: 265a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira cc.mostlyArchive(context, Conversation.listOf(conv)); 2666c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 2676c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira case R.id.delete: 268a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira cc.mostlyDelete(context, Conversation.listOf(conv)); 2696c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira break; 2706c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2716c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira adapter.notifyDataSetChanged(); 272a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira if (mConvSelectionSet != null && !mConvSelectionSet.isEmpty() 273a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira && mConvSelectionSet.contains(conv)) { 274a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira mConvSelectionSet.toggle(null, conv); 275cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira } 276f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 277f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 278f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 279f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public void onBeginDrag(View v) { 280f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira // We do this so the underlying ScrollView knows that it won't get 281f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira // the chance to intercept events anymore 282f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira requestDisallowInterceptTouchEvent(true); 283f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 284f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 285f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 2866c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onDragCancelled(SwipeableItemView v) { 287f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 288f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 28907118a01f7183645957010779222b84930f75b4eMindy Pereira /** 29007118a01f7183645957010779222b84930f75b4eMindy Pereira * Archive items using the swipe away animation before shrinking them away. 29107118a01f7183645957010779222b84930f75b4eMindy Pereira */ 292de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira public void destroyItems(ArrayList<ConversationItemView> views, 29309a4bfe3f81ee216b5c4a4e2d083432a4e387abdVikram Aggarwal final DestructiveAction listener) { 29407118a01f7183645957010779222b84930f75b4eMindy Pereira if (views == null || views.size() == 0) { 29507118a01f7183645957010779222b84930f75b4eMindy Pereira return; 29607118a01f7183645957010779222b84930f75b4eMindy Pereira } 29707118a01f7183645957010779222b84930f75b4eMindy Pereira final ArrayList<Conversation> conversations = new ArrayList<Conversation>(); 29807118a01f7183645957010779222b84930f75b4eMindy Pereira for (ConversationItemView view : views) { 299de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira Conversation conv = view.getConversation(); 300de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira conv.position = view.getParent() != null ? getPositionForView(view) : -1; 301de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira conversations.add(conv); 30207118a01f7183645957010779222b84930f75b4eMindy Pereira } 30307118a01f7183645957010779222b84930f75b4eMindy Pereira mSwipeHelper.dismissChildren(views.get(0), views, new AnimatorListenerAdapter() { 30407118a01f7183645957010779222b84930f75b4eMindy Pereira @Override 30507118a01f7183645957010779222b84930f75b4eMindy Pereira public void onAnimationEnd(Animator animation) { 3060fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira AnimatedAdapter adapter = getAnimatedAdapter(); 3070fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira if (adapter != null) { 3080fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira adapter.delete(conversations, listener); 3090fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira } 31007118a01f7183645957010779222b84930f75b4eMindy Pereira } 31107118a01f7183645957010779222b84930f75b4eMindy Pereira }); 31207118a01f7183645957010779222b84930f75b4eMindy Pereira } 31307118a01f7183645957010779222b84930f75b4eMindy Pereira 3140fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira private AnimatedAdapter getAnimatedAdapter() { 3150fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira return (AnimatedAdapter) getAdapter(); 3160fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira } 3170fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira 318f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public interface SwipeCompleteListener { 319f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public void onSwipeComplete(Collection<Conversation> conversations); 320f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 3218937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira 3228937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira @Override 3238937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira public boolean performItemClick(View view, int pos, long id) { 3248937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // Commit any existing destructive actions when the user selects a conversation to view. 3258937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira commitDestructiveActions(); 3268937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira return super.performItemClick(view, pos, id); 3278937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 3286c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira}