SwipeableListView.java revision 0532b0edb999c6e131bfd1f2e1eccefed049ba49
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;
53f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    /**
54f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     * Are swipes enabled on all items? (Each individual item can still prevent swiping.)<br>
55f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     * When swiping is disabled, the UI still reacts to the gesture to acknowledge it.
56f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     */
57ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira    private boolean mEnableSwipe = false;
58f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    /**
59f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     * When set, we prevent the SwipeHelper from kicking in at all. This
60f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     * short-circuits {@link #mEnableSwipe}.
61f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     */
62f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    private boolean mPreventSwipesEntirely = false;
63489dd22c64c718b6953b4bd6acef925e82c53c87Andy Huang
64b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook    public static final String LOG_TAG = LogTag.getLogTag();
6552a61db87c487fe5bb7cc673037887a6d35b0f0fMark Wei
66ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao    private ConversationCheckedSet mConvCheckedSet;
676c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    private int mSwipeAction;
686126d72ae2769bd39451872f45781cadb5b90515Mark Wei    private Account mAccount;
6906642fab1bf4ab95b5dd97a65b262845cf60c865Mindy Pereira    private Folder mFolder;
709365a826b46b0e274df88e92534f7d871eef2aa2mindyp    private ListItemSwipedListener mSwipedListener;
7169b440141f402669fe44dfd8924a94fd22ebccf7mindyp    private boolean mScrolling;
72866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira
73e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang    private SwipeListener mSwipeListener;
74e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang
750532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    private int mSelectedPosition = ListView.INVALID_POSITION;
760532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao
774485ade4b8c949a222f8b98650a9a48d074dc87eVikram Aggarwal    // Instantiated through view inflation
784485ade4b8c949a222f8b98650a9a48d074dc87eVikram Aggarwal    @SuppressWarnings("unused")
79f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    public SwipeableListView(Context context) {
80f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        this(context, null);
81f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
82f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
83f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    public SwipeableListView(Context context, AttributeSet attrs) {
84f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        this(context, attrs, -1);
85f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
86f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
87f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    public SwipeableListView(Context context, AttributeSet attrs, int defStyle) {
88f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        super(context, attrs, defStyle);
89f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        float densityScale = getResources().getDisplayMetrics().density;
90f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira        float pagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
916f0b2be9d3855e93ec2977b2736798c60adb9b7eMindy Pereira        mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this, densityScale,
926f0b2be9d3855e93ec2977b2736798c60adb9b7eMindy Pereira                pagingTouchSlop);
93f9fd2cf057d845c7b081a3f17482dd0b886179d1Rohan Shah        mScrolling = false;
94f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
95f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
96f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira    @Override
97f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira    protected void onConfigurationChanged(Configuration newConfig) {
98f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira        super.onConfigurationChanged(newConfig);
99f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira        float densityScale = getResources().getDisplayMetrics().density;
100f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira        mSwipeHelper.setDensityScale(densityScale);
101f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
102f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira        mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
103f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira    }
104f913894d3f1fa80b7174477999074b813e1deb12Mindy Pereira
1057517e3b61b898a57f19be0671f70d58a82224643Andy Huang    @Override
1067517e3b61b898a57f19be0671f70d58a82224643Andy Huang    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
107bc88f16af48d9538b79cbeab88cd275cb769a67dVikram Aggarwal        LogUtils.d(Utils.VIEW_DEBUGGING_TAG,
1087517e3b61b898a57f19be0671f70d58a82224643Andy Huang                "START CLF-ListView.onFocusChanged layoutRequested=%s root.layoutRequested=%s",
1097517e3b61b898a57f19be0671f70d58a82224643Andy Huang                isLayoutRequested(), getRootView().isLayoutRequested());
1107517e3b61b898a57f19be0671f70d58a82224643Andy Huang        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
111bc88f16af48d9538b79cbeab88cd275cb769a67dVikram Aggarwal        LogUtils.d(Utils.VIEW_DEBUGGING_TAG, new Error(),
1127517e3b61b898a57f19be0671f70d58a82224643Andy Huang                "FINISH CLF-ListView.onFocusChanged layoutRequested=%s root.layoutRequested=%s",
1137517e3b61b898a57f19be0671f70d58a82224643Andy Huang                isLayoutRequested(), getRootView().isLayoutRequested());
1147517e3b61b898a57f19be0671f70d58a82224643Andy Huang    }
1157517e3b61b898a57f19be0671f70d58a82224643Andy Huang
116ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira    /**
117ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira     * Enable swipe gestures.
118ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira     */
119ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira    public void enableSwipe(boolean enable) {
120ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira        mEnableSwipe = enable;
121ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira    }
122ff9aff3c28c4c20c7866ebfaaa642997e324f274Mindy Pereira
123f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    /**
124f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     * Completely ignore any horizontal swiping gestures.
125f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     */
126f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    public void preventSwipesEntirely() {
127f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang        mPreventSwipesEntirely = true;
128f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    }
129f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang
130f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    /**
131f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     * Reverses a prior call to {@link #preventSwipesEntirely()}.
132f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang     */
133f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    public void stopPreventingSwipes() {
134f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang        mPreventSwipesEntirely = false;
135f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang    }
136f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang
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
149ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao    public void setCheckedSet(ConversationCheckedSet set) {
150ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        mConvCheckedSet = 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
162ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao    public ConversationCheckedSet getCheckedSet() {
163ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        return mConvCheckedSet;
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 {
171f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang            return (!mPreventSwipesEntirely && mSwipeHelper.onInterceptTouchEvent(ev))
172f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang                    || super.onInterceptTouchEvent(ev);
17319bf5f5a4944f5bb4e62e1f32c47dce87f662cbdMindy Pereira        }
174f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
175f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
176f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    @Override
177f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    public boolean onTouchEvent(MotionEvent ev) {
178f211b12a7cdf6556f489df51c6f57dd79e8887feAndy Huang        return (!mPreventSwipesEntirely && mSwipeHelper.onTouchEvent(ev)) || super.onTouchEvent(ev);
179f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
180f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
181f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    @Override
182f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    public View getChildAtPosition(MotionEvent ev) {
183f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        // find the view under the pointer, accounting for GONE views
184f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        final int count = getChildCount();
185f69d0394f7de5c0681b8d5d5ca0c60b55c55f815Vikram Aggarwal        final int touchY = (int) ev.getY();
186f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        int childIdx = 0;
187f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        View slidingChild;
188f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        for (; childIdx < count; childIdx++) {
189f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira            slidingChild = getChildAt(childIdx);
190f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira            if (slidingChild.getVisibility() == GONE) {
191f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira                continue;
192f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira            }
193866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira            if (touchY >= slidingChild.getTop() && touchY <= slidingChild.getBottom()) {
1941ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira                if (slidingChild instanceof SwipeableConversationItemView) {
1951ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira                    return ((SwipeableConversationItemView) slidingChild).getSwipeableItemView();
1961ef988f0c8be136fda75ed207c222413db1d3f0cMindy Pereira                }
197866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira                return slidingChild;
198866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira            }
199f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        }
200f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        return null;
201f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
202f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
203f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    @Override
2046c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public boolean canChildBeDismissed(SwipeableItemView v) {
2053432b636fbcf7d6cc551b9705ed4dd88ae2b4f49Jin Cao        return mEnableSwipe && v.canChildBeDismissed();
206f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
207f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
208f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    @Override
2096c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public void onChildDismissed(SwipeableItemView v) {
2100760bfbf8259e4161ce7737fc980b6b9297885ccmindyp        if (v != null) {
2110760bfbf8259e4161ce7737fc980b6b9297885ccmindyp            v.dismiss();
2120760bfbf8259e4161ce7737fc980b6b9297885ccmindyp        }
213f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
214f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
2158937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira    // Call this whenever a new action is taken; this forces a commit of any
2168937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira    // existing destructive actions.
217c6adce3cf6887c4c6dd5005724565702751843d0mindyp    public void commitDestructiveActions(boolean animate) {
2180fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira        final AnimatedAdapter adapter = getAnimatedAdapter();
2198937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira        if (adapter != null) {
220c6adce3cf6887c4c6dd5005724565702751843d0mindyp            adapter.commitLeaveBehindItems(animate);
2218937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira        }
2228937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira    }
2238937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira
224a538984fcc19e7624f2650b119ede39bf1f35846mindyp    public void dismissChild(final ConversationItemView target) {
2257c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        // Notifies the SwipeListener that a swipe has ended.
2267c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        if (mSwipeListener != null) {
2277c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein            mSwipeListener.onEndSwipe();
2287c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        }
2297c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein
230d3367499e56116854ed637b1036fd71057ac0f49Mindy Pereira        final ToastBarOperation undoOp;
231866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira
2326a3d5ce0b18f58fcfa1af0315dc8ddc7331c2c5fScott Kennedy        undoOp = new ToastBarOperation(1, mSwipeAction, ToastBarOperation.UNDO, false /* batch */,
2336a3d5ce0b18f58fcfa1af0315dc8ddc7331c2c5fScott Kennedy                mFolder);
2346c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        Conversation conv = target.getConversation();
23513e6243683cc8cb998a43d06f25d6ff1aab9d93bMindy Pereira        target.getConversation().position = findConversation(target, conv);
2360fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira        final AnimatedAdapter adapter = getAnimatedAdapter();
23709f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira        if (adapter == null) {
23809f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira            return;
23909f1ae9a9f209436c0c6b44a6e76b32b27937a01Mindy Pereira        }
240370f868c834861e7732faaa9bdd07a0fa0105596Andy Huang        adapter.setupLeaveBehind(conv, undoOp, conv.position, target.getHeight());
24100ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        ConversationCursor cc = (ConversationCursor) adapter.getCursor();
2429365a826b46b0e274df88e92534f7d871eef2aa2mindyp        Collection<Conversation> convList = Conversation.listOf(conv);
2435cc0ab20009100e3ef259fe3d2e3ddc357f79285mindyp        ArrayList<Uri> folderUris;
2445cc0ab20009100e3ef259fe3d2e3ddc357f79285mindyp        ArrayList<Boolean> adds;
245042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huang
2462b55549d4fbe25e91f673a0727fc89ff755d9327Andy Huang        Analytics.getInstance().sendMenuItemEvent("list_swipe", mSwipeAction, null, 0);
247042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huang
2482b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        if (mSwipeAction == R.id.remove_folder) {
2492b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            FolderOperation folderOp = new FolderOperation(mFolder, false);
2502b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            HashMap<Uri, Folder> targetFolders = Folder
2512b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    .hashMapForFolders(conv.getRawFolders());
2522b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            targetFolders.remove(folderOp.mFolder.folderUri.fullUri);
2532b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            final FolderList folders = FolderList.copyOf(targetFolders.values());
2542b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            conv.setRawFolders(folders);
2552b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            final ContentValues values = new ContentValues();
2562b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            folderUris = new ArrayList<Uri>();
2572b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            folderUris.add(mFolder.folderUri.fullUri);
2582b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            adds = new ArrayList<Boolean>();
2592b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            adds.add(Boolean.FALSE);
2602b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            ConversationCursor.addFolderUpdates(folderUris, adds, values);
2612b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            ConversationCursor.addTargetFolders(targetFolders.values(), values);
2622b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            cc.mostlyDestructiveUpdate(Conversation.listOf(conv), values);
2632b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (mSwipeAction == R.id.archive) {
2642b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            cc.mostlyArchive(convList);
2652b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (mSwipeAction == R.id.delete) {
2662b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            cc.mostlyDelete(convList);
267512821c11d89d49908f3cfdee0b582601f500f3dJin Cao        } else if (mSwipeAction == R.id.discard_outbox) {
268512821c11d89d49908f3cfdee0b582601f500f3dJin Cao            cc.moveFailedIntoDrafts(convList);
2696c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        }
2709365a826b46b0e274df88e92534f7d871eef2aa2mindyp        if (mSwipedListener != null) {
2719365a826b46b0e274df88e92534f7d871eef2aa2mindyp            mSwipedListener.onListItemSwiped(convList);
2729365a826b46b0e274df88e92534f7d871eef2aa2mindyp        }
2736c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira        adapter.notifyDataSetChanged();
274ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        if (mConvCheckedSet != null && !mConvCheckedSet.isEmpty()
275ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao                && mConvCheckedSet.contains(conv)) {
276ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao            mConvCheckedSet.toggle(conv);
27754f120f6ada40c7191811dfff99b151e9e192c78mindyp            // Don't commit destructive actions if the item we just removed from
27854f120f6ada40c7191811dfff99b151e9e192c78mindyp            // the selection set is the item we just destroyed!
279ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao            if (!conv.isMostlyDead() && mConvCheckedSet.isEmpty()) {
28054f120f6ada40c7191811dfff99b151e9e192c78mindyp                commitDestructiveActions(true);
28154f120f6ada40c7191811dfff99b151e9e192c78mindyp            }
282cff4a2b2e92258c6c85ed4af15bc13101aa71170Mindy Pereira        }
283f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
284f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
285f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    @Override
286f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    public void onBeginDrag(View v) {
287f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        // We do this so the underlying ScrollView knows that it won't get
288f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        // the chance to intercept events anymore
289f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira        requestDisallowInterceptTouchEvent(true);
2903b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        cancelDismissCounter();
291e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang
2927c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        // Notifies the SwipeListener that a swipe has begun.
293e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang        if (mSwipeListener != null) {
294e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang            mSwipeListener.onBeginSwipe();
295e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang        }
296f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
297f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
298f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    @Override
2996c72a787b58a0bc3afcb71093eddf8c29d1cf5edMindy Pereira    public void onDragCancelled(SwipeableItemView v) {
3003b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        final AnimatedAdapter adapter = getAnimatedAdapter();
3013b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        if (adapter != null) {
3023b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp            adapter.startDismissCounter();
3034d4531a63cff536d2ee1a2929d0820981df8516amindyp            adapter.cancelFadeOutLastLeaveBehindItemText();
3043b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        }
3057c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein
3067c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        // Notifies the SwipeListener that a swipe has ended.
3077c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        if (mSwipeListener != null) {
3087c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein            mSwipeListener.onEndSwipe();
3097c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        }
310f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira    }
311f6a6b50c6b45f36b9317e1688f8b87310a67b037Mindy Pereira
31207118a01f7183645957010779222b84930f75b4eMindy Pereira    /**
31307118a01f7183645957010779222b84930f75b4eMindy Pereira     * Archive items using the swipe away animation before shrinking them away.
31407118a01f7183645957010779222b84930f75b4eMindy Pereira     */
315cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook    public boolean destroyItems(Collection<Conversation> convs,
31684f7d32bdc79263004ed5241480988e02f8e618cmindyp            final ListItemsRemovedListener listener) {
31784f7d32bdc79263004ed5241480988e02f8e618cmindyp        if (convs == null) {
318cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook            LogUtils.e(LOG_TAG, "SwipeableListView.destroyItems: null conversations.");
319cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook            return false;
32084f7d32bdc79263004ed5241480988e02f8e618cmindyp        }
321a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal        final AnimatedAdapter adapter = getAnimatedAdapter();
322a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal        if (adapter == null) {
323a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal            LogUtils.e(LOG_TAG, "SwipeableListView.destroyItems: Cannot destroy: adapter is null.");
324cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook            return false;
325067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        }
32684f7d32bdc79263004ed5241480988e02f8e618cmindyp        adapter.swipeDelete(convs, listener);
327cec3e0b9c90173e0bdb2d072046b38714fc9186ePaul Westbrook        return true;
328067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira    }
329067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira
330cc2f9296ad63ed681c200feb118c5caace36e72emindyp    public int findConversation(ConversationItemView view, Conversation conv) {
331dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy        int position = INVALID_POSITION;
332067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        long convId = conv.id;
333067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        try {
334dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy            position = getPositionForView(view);
335067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        } catch (Exception e) {
336067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira            position = INVALID_POSITION;
337599e7f8bf95d2f21a966cbff1bf72adf77a90a33Andy Huang            LogUtils.w(LOG_TAG, e, "Exception finding position; using alternate strategy");
338067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        }
339067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        if (position == INVALID_POSITION) {
340067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira            // Try the other way!
341067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira            Conversation foundConv;
342067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira            long foundId;
343067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira            for (int i = 0; i < getChildCount(); i++) {
344067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                View child = getChildAt(i);
345067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                if (child instanceof SwipeableConversationItemView) {
346067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                    foundConv = ((SwipeableConversationItemView) child).getSwipeableItemView()
347067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                            .getConversation();
348067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                    foundId = foundConv.id;
349067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                    if (foundId == convId) {
350599e7f8bf95d2f21a966cbff1bf72adf77a90a33Andy Huang                        position = i + getFirstVisiblePosition();
351067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                        break;
352067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                    }
353067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira                }
354067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira            }
355c79aec78d06928b3fa1464d6aed60019f9b4843bMindy Pereira        }
356067ef97264240a2c3f9172a9ab88ba43fef7c475Mindy Pereira        return position;
35707118a01f7183645957010779222b84930f75b4eMindy Pereira    }
35807118a01f7183645957010779222b84930f75b4eMindy Pereira
3590fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira    private AnimatedAdapter getAnimatedAdapter() {
3600fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira        return (AnimatedAdapter) getAdapter();
3610fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira    }
3620fb551891757ecddccb299d9df770bb1675e3fd2Mindy Pereira
3638937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira    @Override
3648937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira    public boolean performItemClick(View view, int pos, long id) {
3656126d72ae2769bd39451872f45781cadb5b90515Mark Wei        // Superclass method modifies the selection set
366f69d0394f7de5c0681b8d5d5ca0c60b55c55f815Vikram Aggarwal        final boolean handled = super.performItemClick(view, pos, id);
3676126d72ae2769bd39451872f45781cadb5b90515Mark Wei
36800ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        // Commit any existing destructive actions when the user selects a
36900ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        // conversation to view.
370c6adce3cf6887c4c6dd5005724565702751843d0mindyp        commitDestructiveActions(true);
371dd9d3a16148b178cb95fd4db4168a67c64eb944fMindy Pereira        return handled;
3728937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira    }
3735254486a8c37cdf2b579aa7a3b9c8eb7324062bcmindyp
3745254486a8c37cdf2b579aa7a3b9c8eb7324062bcmindyp    @Override
375d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp    public void onScroll() {
376d064972c4a032f3c5cfcb236aa470273f7ac2ce0mindyp        commitDestructiveActions(true);
3775254486a8c37cdf2b579aa7a3b9c8eb7324062bcmindyp    }
3789365a826b46b0e274df88e92534f7d871eef2aa2mindyp
3799365a826b46b0e274df88e92534f7d871eef2aa2mindyp    public interface ListItemsRemovedListener {
3809365a826b46b0e274df88e92534f7d871eef2aa2mindyp        public void onListItemsRemoved();
3819365a826b46b0e274df88e92534f7d871eef2aa2mindyp    }
3829365a826b46b0e274df88e92534f7d871eef2aa2mindyp
3839365a826b46b0e274df88e92534f7d871eef2aa2mindyp    public interface ListItemSwipedListener {
3849365a826b46b0e274df88e92534f7d871eef2aa2mindyp        public void onListItemSwiped(Collection<Conversation> conversations);
3859365a826b46b0e274df88e92534f7d871eef2aa2mindyp    }
38669b440141f402669fe44dfd8924a94fd22ebccf7mindyp
38769b440141f402669fe44dfd8924a94fd22ebccf7mindyp    @Override
38879c3e1ed9cb1e1660c5d34b7bf3f3ab5c5dd5162Andy Huang    public final void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
389479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            int totalItemCount) {
39069b440141f402669fe44dfd8924a94fd22ebccf7mindyp    }
39169b440141f402669fe44dfd8924a94fd22ebccf7mindyp
39269b440141f402669fe44dfd8924a94fd22ebccf7mindyp    @Override
39381aea35d45b3d0191ec595562a2fcf67009845d5Mark Wei    public void onScrollStateChanged(final AbsListView view, final int scrollState) {
394479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        mScrolling = scrollState != OnScrollListener.SCROLL_STATE_IDLE;
395479505d71969e26b0785d8e0e1b81108731cf827Mark Wei
39648ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang        if (!mScrolling) {
39748ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang            final Context c = getContext();
39848ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang            if (c instanceof ControllableActivity) {
39948ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang                final ControllableActivity activity = (ControllableActivity) c;
40048ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang                activity.onAnimationEnd(null /* adapter */);
40148ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang            } else {
40248ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang                LogUtils.wtf(LOG_TAG, "unexpected context=%s", c);
40348ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang            }
40448ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang        }
40548ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang    }
40648ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang
40748ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang    public boolean isScrolling() {
40848ccbc53ef90bf6420f831f63e6243008e02a346Andy Huang        return mScrolling;
40969b440141f402669fe44dfd8924a94fd22ebccf7mindyp    }
4103b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp
4110532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    /**
4120532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao     * Set the currently selected (focused by the list view) position.
4130532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao     */
4140532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    public void setSelectedPosition(int position) {
4150532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao        if (position == ListView.INVALID_POSITION) {
4160532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao            return;
4170532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao        }
4180532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao
4190532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao        mSelectedPosition = position;
4200532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    }
4210532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao
4220532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    public boolean isPositionSelected(int position) {
4230532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao        return mSelectedPosition != ListView.INVALID_POSITION && mSelectedPosition == position;
4240532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    }
4250532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao
4260532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    public int getSelectedPosition() {
4270532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao        return mSelectedPosition;
4280532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao    }
4290532b0edb999c6e131bfd1f2e1eccefed049ba49Jin Cao
4303b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp    @Override
4313b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp    public void cancelDismissCounter() {
4323b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        AnimatedAdapter adapter = getAnimatedAdapter();
4333b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        if (adapter != null) {
4343b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp            adapter.cancelDismissCounter();
4353b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp        }
4363b5e82b06a0af3f5ddf3667de9a2aa26eeb5f24bmindyp    }
4377af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp
4387af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp    @Override
4397af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp    public LeaveBehindItem getLastSwipedItem() {
4407af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        AnimatedAdapter adapter = getAnimatedAdapter();
4417af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        if (adapter != null) {
4427af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp            return adapter.getLastLeaveBehindItem();
4437af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        }
4447af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp        return null;
4457af43c93d4ca90bb0a43ec790a434c95128cc99fmindyp    }
446e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang
447e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang    public void setSwipeListener(SwipeListener swipeListener) {
448e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang        mSwipeListener = swipeListener;
449e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang    }
450e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang
451e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang    public interface SwipeListener {
452e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang        public void onBeginSwipe();
4537c411aafd9ef059f881b7532426e61d1def54a07Andrew Sapperstein        public void onEndSwipe();
454e6f4ddc19c205796cde91d58483fa39c3cc13f1aAlice Yang    }
45500ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira}
456