SwipeableListView.java revision 3432b636fbcf7d6cc551b9705ed4dd88ae2b4f49
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 20b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huangimport android.content.ContentValues; 21f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport android.content.Context; 22f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereiraimport android.content.res.Configuration; 237517e3b61b898a57f19be0671f70d58a82224643Andy Huangimport android.graphics.Rect; 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; 297c411aafd9ef059f881b7532426e61d1def54a07Andrew Sappersteinimport android.widget.AbsListView; 307c411aafd9ef059f881b7532426e61d1def54a07Andrew Sappersteinimport android.widget.AbsListView.OnScrollListener; 31f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport android.widget.ListView; 32f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 33f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.R; 34042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huangimport com.android.mail.analytics.Analytics; 35bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport com.android.mail.browse.ConversationCursor; 36f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.browse.ConversationItemView; 371ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereiraimport com.android.mail.browse.SwipeableConversationItemView; 386126d72ae2769bd39451872f45781cadb5b90515Mark Weiimport com.android.mail.providers.Account; 39f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.providers.Conversation; 4006642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereiraimport com.android.mail.providers.Folder; 41b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huangimport com.android.mail.providers.FolderList; 42f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport com.android.mail.ui.SwipeHelper.Callback; 43b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag; 44b0219eb7b77212902a38821c050922ac73a68250Mindy Pereiraimport com.android.mail.utils.LogUtils; 457517e3b61b898a57f19be0671f70d58a82224643Andy Huangimport com.android.mail.utils.Utils; 46f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 47866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereiraimport java.util.ArrayList; 48f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereiraimport java.util.Collection; 498db7e407109532557718c6b8064792f2df7a073dMindy Pereiraimport java.util.HashMap; 50f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 5169b440141f402669fe44dfd8924a94fd22ebccf7mindyppublic class SwipeableListView extends ListView implements Callback, OnScrollListener { 526126d72ae2769bd39451872f45781cadb5b90515Mark Wei private final SwipeHelper mSwipeHelper; 53ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira private boolean mEnableSwipe = false; 54489dd22c64c718b6953b4bd6acef925e82c53c87Andy Huang 55b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook public static final String LOG_TAG = LogTag.getLogTag(); 56479505d71969e26b0785d8e0e1b81108731cf827Mark Wei /** 57479505d71969e26b0785d8e0e1b81108731cf827Mark Wei * Set to false to prevent the FLING scroll state from pausing the photo manager loaders. 58479505d71969e26b0785d8e0e1b81108731cf827Mark Wei */ 59479505d71969e26b0785d8e0e1b81108731cf827Mark Wei private final static boolean SCROLL_PAUSE_ENABLE = true; 60f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 6179c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang /** 6279c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang * Set to true to enable parallax effect for attachment previews as the scroll position varies. 6379c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang * This effect triggers invalidations on scroll (!) and requires more memory for attachment 6479c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang * preview bitmaps. 6579c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang */ 6679c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang public static final boolean ENABLE_ATTACHMENT_PARALLAX = true; 6765b6d180f50922a3393795203cae68a5a2f6a33dMark Wei 6865b6d180f50922a3393795203cae68a5a2f6a33dMark Wei /** 6965b6d180f50922a3393795203cae68a5a2f6a33dMark Wei * Set to true to queue finished decodes in an aggregator so that we display decoded attachment 7065b6d180f50922a3393795203cae68a5a2f6a33dMark Wei * previews in an ordered fashion. This artificially delays updating the UI with decoded images, 7165b6d180f50922a3393795203cae68a5a2f6a33dMark Wei * since they may have to wait on another image to finish decoding first. 7265b6d180f50922a3393795203cae68a5a2f6a33dMark Wei */ 7365b6d180f50922a3393795203cae68a5a2f6a33dMark Wei public static final boolean ENABLE_ATTACHMENT_DECODE_AGGREGATOR = true; 7479c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang 7579c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang /** 7679c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang * The amount of extra vertical space to decode in attachment previews so we have image data to 7779c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang * pan within. 1.0 implies no parallax effect. 7879c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang */ 79901bf8b70ead9af21652c0f01fd9b87b2c7efc6cMark Wei public static final float ATTACHMENT_PARALLAX_MULTIPLIER_NORMAL = 1.5f; 80901bf8b70ead9af21652c0f01fd9b87b2c7efc6cMark Wei public static final float ATTACHMENT_PARALLAX_MULTIPLIER_ALTERNATIVE = 2.0f; 8152a61db87c487fe5bb7cc673037887a6d35b0f0fMark Wei 82866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira private ConversationSelectionSet mConvSelectionSet; 836c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira private int mSwipeAction; 846126d72ae2769bd39451872f45781cadb5b90515Mark Wei private Account mAccount; 8506642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira private Folder mFolder; 869365a826b46b0e274df88e92534f7d871eef2aa2mindyp private ListItemSwipedListener mSwipedListener; 8769b440141f402669fe44dfd8924a94fd22ebccf7mindyp private boolean mScrolling; 88866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 89e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang private SwipeListener mSwipeListener; 90e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang 914485ade4b8c949a222f8b98650a9a48d074dc87eVikram Aggarwal // Instantiated through view inflation 924485ade4b8c949a222f8b98650a9a48d074dc87eVikram Aggarwal @SuppressWarnings("unused") 93f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context) { 94f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira this(context, null); 95f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 96f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 97f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context, AttributeSet attrs) { 98f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira this(context, attrs, -1); 99f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 100f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 101f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public SwipeableListView(Context context, AttributeSet attrs, int defStyle) { 102f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira super(context, attrs, defStyle); 1032229eddfba6f7517c43ef49ee67c50c24d4b961aMark Wei setOnScrollListener(this); 104f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira float densityScale = getResources().getDisplayMetrics().density; 105f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float pagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); 1066f0b2be9d3855e93ec2977b2736798c60adb9b7eMindy Pereira mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this, densityScale, 1076f0b2be9d3855e93ec2977b2736798c60adb9b7eMindy Pereira pagingTouchSlop); 108f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 109f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 110f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira @Override 111f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira protected void onConfigurationChanged(Configuration newConfig) { 112f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira super.onConfigurationChanged(newConfig); 113f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float densityScale = getResources().getDisplayMetrics().density; 114f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper.setDensityScale(densityScale); 115f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop(); 116f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira mSwipeHelper.setPagingTouchSlop(pagingTouchSlop); 117f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira } 118f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira 1197517e3b61b898a57f19be0671f70d58a82224643Andy Huang @Override 1207517e3b61b898a57f19be0671f70d58a82224643Andy Huang protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { 121bc88f16af48d9538b79cbeab88cd275cb769a67dVikram Aggarwal LogUtils.d(Utils.VIEW_DEBUGGING_TAG, 1227517e3b61b898a57f19be0671f70d58a82224643Andy Huang "START CLF-ListView.onFocusChanged layoutRequested=%s root.layoutRequested=%s", 1237517e3b61b898a57f19be0671f70d58a82224643Andy Huang isLayoutRequested(), getRootView().isLayoutRequested()); 1247517e3b61b898a57f19be0671f70d58a82224643Andy Huang super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); 125bc88f16af48d9538b79cbeab88cd275cb769a67dVikram Aggarwal LogUtils.d(Utils.VIEW_DEBUGGING_TAG, new Error(), 1267517e3b61b898a57f19be0671f70d58a82224643Andy Huang "FINISH CLF-ListView.onFocusChanged layoutRequested=%s root.layoutRequested=%s", 1277517e3b61b898a57f19be0671f70d58a82224643Andy Huang isLayoutRequested(), getRootView().isLayoutRequested()); 1287517e3b61b898a57f19be0671f70d58a82224643Andy Huang } 1297517e3b61b898a57f19be0671f70d58a82224643Andy Huang 130ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira /** 131ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira * Enable swipe gestures. 132ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira */ 133ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira public void enableSwipe(boolean enable) { 134ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira mEnableSwipe = enable; 135ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira } 136ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira 1376c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void setSwipeAction(int action) { 1386c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira mSwipeAction = action; 139f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 140f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 1417c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein public void setListItemSwipedListener(ListItemSwipedListener listener) { 1429365a826b46b0e274df88e92534f7d871eef2aa2mindyp mSwipedListener = listener; 1439365a826b46b0e274df88e92534f7d871eef2aa2mindyp } 1449365a826b46b0e274df88e92534f7d871eef2aa2mindyp 145de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira public int getSwipeAction() { 146de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira return mSwipeAction; 147de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira } 148de3e74a82043733243c7391d7f983a5af8842891Mindy Pereira 149866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public void setSelectionSet(ConversationSelectionSet set) { 150866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mConvSelectionSet = set; 151866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 152866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 1536126d72ae2769bd39451872f45781cadb5b90515Mark Wei public void setCurrentAccount(Account account) { 1546126d72ae2769bd39451872f45781cadb5b90515Mark Wei mAccount = account; 1556126d72ae2769bd39451872f45781cadb5b90515Mark Wei } 1566126d72ae2769bd39451872f45781cadb5b90515Mark Wei 15706642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira public void setCurrentFolder(Folder folder) { 15806642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira mFolder = folder; 15906642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira } 16006642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira 161866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira @Override 162866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public ConversationSelectionSet getSelectionSet() { 163866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira return mConvSelectionSet; 164866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 165866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 166f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 167f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public boolean onInterceptTouchEvent(MotionEvent ev) { 1683432b636fbcf7d6cc551b9705ed4dd88ae2b4f49Jin Cao if (mScrolling) { 16919bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira return super.onInterceptTouchEvent(ev); 17069b440141f402669fe44dfd8924a94fd22ebccf7mindyp } else { 17169b440141f402669fe44dfd8924a94fd22ebccf7mindyp return mSwipeHelper.onInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev); 17219bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira } 173f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 174f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 175f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 176f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public boolean onTouchEvent(MotionEvent ev) { 1773432b636fbcf7d6cc551b9705ed4dd88ae2b4f49Jin Cao return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev); 178f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 179f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 180f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 181f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira public View getChildAtPosition(MotionEvent ev) { 182f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira // find the view under the pointer, accounting for GONE views 183f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira final int count = getChildCount(); 184f69d0394f7de5c0681b8d5d5ca0c60b55c55f815Vikram Aggarwal final int touchY = (int) ev.getY(); 185f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira int childIdx = 0; 186f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira View slidingChild; 187f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira for (; childIdx < count; childIdx++) { 188f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira slidingChild = getChildAt(childIdx); 189f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira if (slidingChild.getVisibility() == GONE) { 190f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira continue; 191f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 192866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira if (touchY >= slidingChild.getTop() && touchY <= slidingChild.getBottom()) { 1931ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira if (slidingChild instanceof SwipeableConversationItemView) { 1941ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira return ((SwipeableConversationItemView) slidingChild).getSwipeableItemView(); 1951ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira } 196866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira return slidingChild; 197866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 198f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 199f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira return null; 200f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 201f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 202f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 2036c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public boolean canChildBeDismissed(SwipeableItemView v) { 2043432b636fbcf7d6cc551b9705ed4dd88ae2b4f49Jin Cao return mEnableSwipe && v.canChildBeDismissed(); 205f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 206f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 207f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 2086c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onChildDismissed(SwipeableItemView v) { 2090760bfbf8259e4161ce7737fc980b6b9297885ccmindyp if (v != null) { 2100760bfbf8259e4161ce7737fc980b6b9297885ccmindyp v.dismiss(); 2110760bfbf8259e4161ce7737fc980b6b9297885ccmindyp } 212f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 213f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 2148937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // Call this whenever a new action is taken; this forces a commit of any 2158937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira // existing destructive actions. 216c6adce3cf6887c4c6dd5005724565702751843d0mindyp public void commitDestructiveActions(boolean animate) { 2170fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 2188937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira if (adapter != null) { 219c6adce3cf6887c4c6dd5005724565702751843d0mindyp adapter.commitLeaveBehindItems(animate); 2208937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 2218937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 2228937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira 223a538984fcc19e7624f2650b119ede39bf1f35846mindyp public void dismissChild(final ConversationItemView target) { 2247c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein // Notifies the SwipeListener that a swipe has ended. 2257c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein if (mSwipeListener != null) { 2267c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein mSwipeListener.onEndSwipe(); 2277c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein } 2287c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein 229d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira final ToastBarOperation undoOp; 230866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 2316a3d5ce0b18f58fcfa1af0315dc8ddc7331c2c5fScott Kennedy undoOp = new ToastBarOperation(1, mSwipeAction, ToastBarOperation.UNDO, false /* batch */, 2326a3d5ce0b18f58fcfa1af0315dc8ddc7331c2c5fScott Kennedy mFolder); 2336c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira Conversation conv = target.getConversation(); 23413e6243683cc8cb998a43d06f25d6ff1aab9d93bMindy Pereira target.getConversation().position = findConversation(target, conv); 2350fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira final AnimatedAdapter adapter = getAnimatedAdapter(); 23609f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira if (adapter == null) { 23709f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira return; 23809f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira } 239370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang adapter.setupLeaveBehind(conv, undoOp, conv.position, target.getHeight()); 24000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira ConversationCursor cc = (ConversationCursor) adapter.getCursor(); 2419365a826b46b0e274df88e92534f7d871eef2aa2mindyp Collection<Conversation> convList = Conversation.listOf(conv); 2425cc0ab20009100e3ef259fe3d2e3ddc357f79285mindyp ArrayList<Uri> folderUris; 2435cc0ab20009100e3ef259fe3d2e3ddc357f79285mindyp ArrayList<Boolean> adds; 244042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huang 2452b55549d4fbe25e91f673a0727fc89ff755d9327Andy Huang Analytics.getInstance().sendMenuItemEvent("list_swipe", mSwipeAction, null, 0); 246042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huang 2472b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy if (mSwipeAction == R.id.remove_folder) { 2482b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy FolderOperation folderOp = new FolderOperation(mFolder, false); 2492b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy HashMap<Uri, Folder> targetFolders = Folder 2502b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy .hashMapForFolders(conv.getRawFolders()); 2512b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy targetFolders.remove(folderOp.mFolder.folderUri.fullUri); 2522b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy final FolderList folders = FolderList.copyOf(targetFolders.values()); 2532b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy conv.setRawFolders(folders); 2542b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy final ContentValues values = new ContentValues(); 2552b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy folderUris = new ArrayList<Uri>(); 2562b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy folderUris.add(mFolder.folderUri.fullUri); 2572b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy adds = new ArrayList<Boolean>(); 2582b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy adds.add(Boolean.FALSE); 2592b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy ConversationCursor.addFolderUpdates(folderUris, adds, values); 2602b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy ConversationCursor.addTargetFolders(targetFolders.values(), values); 2612b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy cc.mostlyDestructiveUpdate(Conversation.listOf(conv), values); 2622b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy } else if (mSwipeAction == R.id.archive) { 2632b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy cc.mostlyArchive(convList); 2642b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy } else if (mSwipeAction == R.id.delete) { 2652b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy cc.mostlyDelete(convList); 2666c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira } 2679365a826b46b0e274df88e92534f7d871eef2aa2mindyp if (mSwipedListener != null) { 2689365a826b46b0e274df88e92534f7d871eef2aa2mindyp mSwipedListener.onListItemSwiped(convList); 2699365a826b46b0e274df88e92534f7d871eef2aa2mindyp } 2706c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira adapter.notifyDataSetChanged(); 271a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira if (mConvSelectionSet != null && !mConvSelectionSet.isEmpty() 272a8ead90ce1e6c66e4ecacdf7cfa25c2cafc9bb3bMindy Pereira && mConvSelectionSet.contains(conv)) { 27320a97ded277fdcd3c63952a23718410c2882103fVikram Aggarwal mConvSelectionSet.toggle(conv); 27454f120f6ada40c7191811dfff99b151e9e192c78mindyp // Don't commit destructive actions if the item we just removed from 27554f120f6ada40c7191811dfff99b151e9e192c78mindyp // the selection set is the item we just destroyed! 27654f120f6ada40c7191811dfff99b151e9e192c78mindyp if (!conv.isMostlyDead() && mConvSelectionSet.isEmpty()) { 27754f120f6ada40c7191811dfff99b151e9e192c78mindyp commitDestructiveActions(true); 27854f120f6ada40c7191811dfff99b151e9e192c78mindyp } 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); 2873b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp cancelDismissCounter(); 288e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang 2897c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein // Notifies the SwipeListener that a swipe has begun. 290e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang if (mSwipeListener != null) { 291e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang mSwipeListener.onBeginSwipe(); 292e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang } 293f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 294f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 295f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira @Override 2966c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira public void onDragCancelled(SwipeableItemView v) { 2973b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp final AnimatedAdapter adapter = getAnimatedAdapter(); 2983b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp if (adapter != null) { 2993b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp adapter.startDismissCounter(); 3004d4531a63cff536d2ee1a2929d0820981df8516amindyp adapter.cancelFadeOutLastLeaveBehindItemText(); 3013b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp } 3027c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein 3037c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein // Notifies the SwipeListener that a swipe has ended. 3047c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein if (mSwipeListener != null) { 3057c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein mSwipeListener.onEndSwipe(); 3067c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein } 307f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira } 308f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira 30907118a01f7183645957010779222b84930f75b4eMindy Pereira /** 31007118a01f7183645957010779222b84930f75b4eMindy Pereira * Archive items using the swipe away animation before shrinking them away. 31107118a01f7183645957010779222b84930f75b4eMindy Pereira */ 312cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook public boolean destroyItems(Collection<Conversation> convs, 31384f7d32bdc79263004ed5241480988e02f8e618cmindyp final ListItemsRemovedListener listener) { 31484f7d32bdc79263004ed5241480988e02f8e618cmindyp if (convs == null) { 315cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook LogUtils.e(LOG_TAG, "SwipeableListView.destroyItems: null conversations."); 316cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook return false; 31784f7d32bdc79263004ed5241480988e02f8e618cmindyp } 318a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal final AnimatedAdapter adapter = getAnimatedAdapter(); 319a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal if (adapter == null) { 320a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal LogUtils.e(LOG_TAG, "SwipeableListView.destroyItems: Cannot destroy: adapter is null."); 321cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook return false; 322067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira } 32384f7d32bdc79263004ed5241480988e02f8e618cmindyp adapter.swipeDelete(convs, listener); 324cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook return true; 325067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira } 326067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira 327cc2f9296ad63ed681c200feb118c5caace36e72emindyp public int findConversation(ConversationItemView view, Conversation conv) { 328dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy int position = INVALID_POSITION; 329067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira long convId = conv.id; 330067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira try { 331dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy position = getPositionForView(view); 332067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira } catch (Exception e) { 333067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira position = INVALID_POSITION; 334599e7f8bf95d2f21a966cbff1bf72adf77a90a33Andy Huang LogUtils.w(LOG_TAG, e, "Exception finding position; using alternate strategy"); 335067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira } 336067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira if (position == INVALID_POSITION) { 337067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira // Try the other way! 338067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira Conversation foundConv; 339067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira long foundId; 340067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira for (int i = 0; i < getChildCount(); i++) { 341067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira View child = getChildAt(i); 342067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira if (child instanceof SwipeableConversationItemView) { 343067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira foundConv = ((SwipeableConversationItemView) child).getSwipeableItemView() 344067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira .getConversation(); 345067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira foundId = foundConv.id; 346067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira if (foundId == convId) { 347599e7f8bf95d2f21a966cbff1bf72adf77a90a33Andy Huang position = i + getFirstVisiblePosition(); 348067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira break; 349067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira } 350067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira } 351067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira } 352c79aec78d06928b3fa1464d6aed60019f9b4843bMindy Pereira } 353067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira return position; 35407118a01f7183645957010779222b84930f75b4eMindy Pereira } 35507118a01f7183645957010779222b84930f75b4eMindy Pereira 3560fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira private AnimatedAdapter getAnimatedAdapter() { 3570fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira return (AnimatedAdapter) getAdapter(); 3580fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira } 3590fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira 3608937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira @Override 3618937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira public boolean performItemClick(View view, int pos, long id) { 362f69d0394f7de5c0681b8d5d5ca0c60b55c55f815Vikram Aggarwal final int previousPosition = getCheckedItemPosition(); 363f69d0394f7de5c0681b8d5d5ca0c60b55c55f815Vikram Aggarwal final boolean selectionSetEmpty = mConvSelectionSet.isEmpty(); 3646126d72ae2769bd39451872f45781cadb5b90515Mark Wei 3656126d72ae2769bd39451872f45781cadb5b90515Mark Wei // Superclass method modifies the selection set 366f69d0394f7de5c0681b8d5d5ca0c60b55c55f815Vikram Aggarwal final boolean handled = super.performItemClick(view, pos, id); 3676126d72ae2769bd39451872f45781cadb5b90515Mark Wei 3681fea6a3cffcc8c4afc3d877e5dc57d29f9665942Scott Kennedy // If we are in CAB mode then a click shouldn't 3696126d72ae2769bd39451872f45781cadb5b90515Mark Wei // activate the new item, it should only add it to the selection set 3701fea6a3cffcc8c4afc3d877e5dc57d29f9665942Scott Kennedy if (!selectionSetEmpty && previousPosition != -1) { 3716126d72ae2769bd39451872f45781cadb5b90515Mark Wei setItemChecked(previousPosition, true); 3726126d72ae2769bd39451872f45781cadb5b90515Mark Wei } 37300ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira // Commit any existing destructive actions when the user selects a 37400ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira // conversation to view. 375c6adce3cf6887c4c6dd5005724565702751843d0mindyp commitDestructiveActions(true); 376dd9d3a16148b178cb95fd4db4168a67c64eb944fMindy Pereira return handled; 3778937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira } 3785254486a8c37cdf2b579aa7a3b9c8eb7324062bcmindyp 3795254486a8c37cdf2b579aa7a3b9c8eb7324062bcmindyp @Override 380d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp public void onScroll() { 381d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp commitDestructiveActions(true); 3825254486a8c37cdf2b579aa7a3b9c8eb7324062bcmindyp } 3839365a826b46b0e274df88e92534f7d871eef2aa2mindyp 3849365a826b46b0e274df88e92534f7d871eef2aa2mindyp public interface ListItemsRemovedListener { 3859365a826b46b0e274df88e92534f7d871eef2aa2mindyp public void onListItemsRemoved(); 3869365a826b46b0e274df88e92534f7d871eef2aa2mindyp } 3879365a826b46b0e274df88e92534f7d871eef2aa2mindyp 3889365a826b46b0e274df88e92534f7d871eef2aa2mindyp public interface ListItemSwipedListener { 3899365a826b46b0e274df88e92534f7d871eef2aa2mindyp public void onListItemSwiped(Collection<Conversation> conversations); 3909365a826b46b0e274df88e92534f7d871eef2aa2mindyp } 39169b440141f402669fe44dfd8924a94fd22ebccf7mindyp 39269b440141f402669fe44dfd8924a94fd22ebccf7mindyp @Override 39379c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang public final void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 394479505d71969e26b0785d8e0e1b81108731cf827Mark Wei int totalItemCount) { 39579c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang if (ENABLE_ATTACHMENT_PARALLAX) { 39679c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang for (int i = 0, len = getChildCount(); i < len; i++) { 39779c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang final View child = getChildAt(i); 39879c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang if (child instanceof OnScrollListener) { 39979c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang ((OnScrollListener) child).onScroll(view, firstVisibleItem, visibleItemCount, 40079c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang totalItemCount); 40179c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang } 40279c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang } 40379c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang } 40469b440141f402669fe44dfd8924a94fd22ebccf7mindyp } 40569b440141f402669fe44dfd8924a94fd22ebccf7mindyp 40669b440141f402669fe44dfd8924a94fd22ebccf7mindyp @Override 40781aea35d45b3d0191ec595562a2fcf67009845d5Mark Wei public void onScrollStateChanged(final AbsListView view, final int scrollState) { 408479505d71969e26b0785d8e0e1b81108731cf827Mark Wei mScrolling = scrollState != OnScrollListener.SCROLL_STATE_IDLE; 409479505d71969e26b0785d8e0e1b81108731cf827Mark Wei 41048ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang if (!mScrolling) { 41148ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang final Context c = getContext(); 41248ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang if (c instanceof ControllableActivity) { 41348ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang final ControllableActivity activity = (ControllableActivity) c; 41448ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang activity.onAnimationEnd(null /* adapter */); 41548ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang } else { 41648ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang LogUtils.wtf(LOG_TAG, "unexpected context=%s", c); 41748ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang } 41848ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang } 419479505d71969e26b0785d8e0e1b81108731cf827Mark Wei 420479505d71969e26b0785d8e0e1b81108731cf827Mark Wei if (SCROLL_PAUSE_ENABLE) { 421670c280136f587688d41027ce1ff1596068a35e0Mark Wei AnimatedAdapter adapter = getAnimatedAdapter(); 422670c280136f587688d41027ce1ff1596068a35e0Mark Wei if (adapter != null) { 423670c280136f587688d41027ce1ff1596068a35e0Mark Wei adapter.onScrollStateChanged(scrollState); 424670c280136f587688d41027ce1ff1596068a35e0Mark Wei } 425479505d71969e26b0785d8e0e1b81108731cf827Mark Wei } 42648ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang } 42748ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang 42848ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang public boolean isScrolling() { 42948ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang return mScrolling; 43069b440141f402669fe44dfd8924a94fd22ebccf7mindyp } 4313b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp 4323b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp @Override 4333b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp public void cancelDismissCounter() { 4343b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp AnimatedAdapter adapter = getAnimatedAdapter(); 4353b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp if (adapter != null) { 4363b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp adapter.cancelDismissCounter(); 4373b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp } 4383b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp } 4397af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp 4407af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp @Override 4417af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp public LeaveBehindItem getLastSwipedItem() { 4427af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp AnimatedAdapter adapter = getAnimatedAdapter(); 4437af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp if (adapter != null) { 4447af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp return adapter.getLastLeaveBehindItem(); 4457af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp } 4467af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp return null; 4477af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp } 448e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang 449e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang public void setSwipeListener(SwipeListener swipeListener) { 450e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang mSwipeListener = swipeListener; 451e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang } 452e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang 453e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang public interface SwipeListener { 454e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang public void onBeginSwipe(); 4557c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein public void onEndSwipe(); 456e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang } 45700ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira} 458