107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka/* 207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * Copyright (C) 2011 The Android Open Source Project 307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * 407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * you may not use this file except in compliance with the License. 607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * You may obtain a copy of the License at 707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * 807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * http://www.apache.org/licenses/LICENSE-2.0 907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * 1007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * Unless required by applicable law or agreed to in writing, software 1107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 1207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * See the License for the specific language governing permissions and 1407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka * limitations under the License. 1507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka */ 1607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 1707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkapackage com.android.systemui; 1807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 1907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.animation.Animator; 202f2022afa1eb85018368398bd150e9575fc099c9Chet Haaseimport android.animation.AnimatorListenerAdapter; 2107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.animation.ObjectAnimator; 2207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.animation.ValueAnimator; 2307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.animation.ValueAnimator.AnimatorUpdateListener; 24eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandlerimport android.content.Context; 2507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.graphics.RectF; 26f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandlerimport android.os.Handler; 2707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.util.Log; 2807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.view.MotionEvent; 2907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.view.VelocityTracker; 3007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurkaimport android.view.View; 31f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandlerimport android.view.ViewConfiguration; 32de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.view.accessibility.AccessibilityEvent; 3307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 346dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowskiimport com.android.systemui.classifier.FalsingManager; 3595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; 3695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem; 3795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.statusbar.ExpandableNotificationRow; 38287963146c96a4cd2772cfee829ac4a4a03c1ff7Mady Mellorimport com.android.systemui.statusbar.FlingAnimationUtils; 396dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski 4030637e41c9497576fa644c5ac0bf0864d3a52c5fdongwanimport java.util.HashMap; 4130637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan 426a858c347f4d4e5db4c8f00d5e285967631b71caDaniel Sandlerpublic class SwipeHelper implements Gefingerpoken { 4307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka static final String TAG = "com.android.systemui.SwipeHelper"; 4496f4818ef41141649337d4dee09f837594e93d09Daniel Sandler private static final boolean DEBUG = false; 4507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private static final boolean DEBUG_INVALIDATE = false; 4607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private static final boolean SLOW_ANIMATIONS = false; // DEBUG; 473cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka private static final boolean CONSTRAIN_SWIPE = true; 483cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka private static final boolean FADE_OUT_DURING_SWIPE = true; 493cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true; 5007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 5107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public static final int X = 0; 5207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public static final int Y = 1; 5307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 545574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor private float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec 550e8063a3b447e1aa5cc3171db42f735b3b6ae78eMichael Jurka private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms 560e8063a3b447e1aa5cc3171db42f735b3b6ae78eMichael Jurka private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms 57bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson private int MAX_DISMISS_VELOCITY = 4000; // dp/sec 580e8063a3b447e1aa5cc3171db42f735b3b6ae78eMichael Jurka private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms 5907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 605d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width 615d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos // beyond which swipe progress->0 625574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor public static final float SWIPED_FAR_ENOUGH_SIZE_FRACTION = 0.6f; 635574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor static final float MAX_SCROLL_SIZE_FRACTION = 0.3f; 645574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor 655d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos private float mMinSwipeProgress = 0f; 665d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos private float mMaxSwipeProgress = 1f; 6707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 68287963146c96a4cd2772cfee829ac4a4a03c1ff7Mady Mellor private FlingAnimationUtils mFlingAnimationUtils; 6907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private float mPagingTouchSlop; 7007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private Callback mCallback; 71f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler private Handler mHandler; 7207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private int mSwipeDirection; 7307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private VelocityTracker mVelocityTracker; 746dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski private FalsingManager mFalsingManager; 7507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 7607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private float mInitialTouchPos; 779b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi private float mPerpendicularInitialTouchPos; 7807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private boolean mDragging; 7930637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan private boolean mSnappingChild; 8007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private View mCurrView; 813cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka private boolean mCanCurrViewBeDimissed; 8207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private float mDensityScale; 834b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor private float mTranslation = 0; 8407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 85f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler private boolean mLongPressSent; 864247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler private LongPressListener mLongPressListener; 87f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler private Runnable mWatchLongPress; 88469e96e206f8df44b32ce393f8d19f0cae730030Daniel Sandler private long mLongPressTimeout; 89f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler 904247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler final private int[] mTmpPos = new int[2]; 9119c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek private int mFalsingThreshold; 9219c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek private boolean mTouchAboveFalsingThreshold; 93671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson private boolean mDisableHwLayers; 9443c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor private Context mContext; 954247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler 9630637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan private HashMap<View, Animator> mDismissPendingMap = new HashMap<>(); 9730637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan 98eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler public SwipeHelper(int swipeDirection, Callback callback, Context context) { 9943c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor mContext = context; 10007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mCallback = callback; 101f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler mHandler = new Handler(); 10207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mSwipeDirection = swipeDirection; 10307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mVelocityTracker = VelocityTracker.obtain(); 104eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler mDensityScale = context.getResources().getDisplayMetrics().density; 105eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop(); 106469e96e206f8df44b32ce393f8d19f0cae730030Daniel Sandler 107469e96e206f8df44b32ce393f8d19f0cae730030Daniel Sandler mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press! 10819c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek mFalsingThreshold = context.getResources().getDimensionPixelSize( 10919c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek R.dimen.swipe_helper_falsing_threshold); 1106dc59b48c040cf6871d7ff6d8e5242b1a5ddd032Blazej Magnowski mFalsingManager = FalsingManager.getInstance(context); 111bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f); 11207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 11307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 1144247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler public void setLongPressListener(LongPressListener listener) { 115f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler mLongPressListener = listener; 116f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 117f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler 11807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public void setDensityScale(float densityScale) { 11907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mDensityScale = densityScale; 12007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 12107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 12207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public void setPagingTouchSlop(float pagingTouchSlop) { 12307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mPagingTouchSlop = pagingTouchSlop; 12407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 12507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 126671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson public void setDisableHardwareLayers(boolean disableHwLayers) { 127671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson mDisableHwLayers = disableHwLayers; 128671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson } 129671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson 13007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private float getPos(MotionEvent ev) { 13107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka return mSwipeDirection == X ? ev.getX() : ev.getY(); 13207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 13307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 1349b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi private float getPerpendicularPos(MotionEvent ev) { 1359b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi return mSwipeDirection == X ? ev.getY() : ev.getX(); 1369b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi } 1379b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi 1384b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor protected float getTranslation(View v) { 1393cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY(); 14007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 14107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 14207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private float getVelocity(VelocityTracker vt) { 14307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka return mSwipeDirection == X ? vt.getXVelocity() : 14407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka vt.getYVelocity(); 14507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 14607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 1474b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor protected ObjectAnimator createTranslationAnimation(View v, float newPos) { 14807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka ObjectAnimator anim = ObjectAnimator.ofFloat(v, 149c5fd350522d9269e6239af818f7261a6ead51570Winson mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos); 15007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka return anim; 15107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 15207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 15307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka private float getPerpendicularVelocity(VelocityTracker vt) { 15407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka return mSwipeDirection == X ? vt.getYVelocity() : 15507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka vt.getXVelocity(); 15607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 15707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 1584b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor protected Animator getViewTranslationAnimator(View v, float target, 1594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor AnimatorUpdateListener listener) { 1604b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor ObjectAnimator anim = createTranslationAnimation(v, target); 16134958fa272c9216db4002546c3efad692b3d7775Mady Mellor if (listener != null) { 16234958fa272c9216db4002546c3efad692b3d7775Mady Mellor anim.addUpdateListener(listener); 16334958fa272c9216db4002546c3efad692b3d7775Mady Mellor } 1644b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor return anim; 1654b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor } 1664b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor 1674b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor protected void setTranslation(View v, float translate) { 1684b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor if (v == null) { 1694b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor return; 1704b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor } 17107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka if (mSwipeDirection == X) { 17207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka v.setTranslationX(translate); 17307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } else { 17407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka v.setTranslationY(translate); 17507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 17607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 17707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 178671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson protected float getSize(View v) { 17907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka return mSwipeDirection == X ? v.getMeasuredWidth() : 18007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka v.getMeasuredHeight(); 18107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 18207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 1835d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos public void setMinSwipeProgress(float minSwipeProgress) { 1845d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos mMinSwipeProgress = minSwipeProgress; 1854eaa983f253d0215d4de777edd8616318610ea22Michael Jurka } 1864eaa983f253d0215d4de777edd8616318610ea22Michael Jurka 1875d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos public void setMaxSwipeProgress(float maxSwipeProgress) { 1885d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos mMaxSwipeProgress = maxSwipeProgress; 189de61fd7822ea15fb691405c1aae472caa58e83baAdrian Roos } 190de61fd7822ea15fb691405c1aae472caa58e83baAdrian Roos 191bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson private float getSwipeProgressForOffset(View view, float translation) { 1923cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka float viewSize = getSize(view); 193bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson float result = Math.abs(translation / viewSize); 1945d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos return Math.min(Math.max(mMinSwipeProgress, result), mMaxSwipeProgress); 19507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 19607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 197bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson private float getSwipeAlpha(float progress) { 198bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson return Math.min(0, Math.max(1, progress / SWIPE_PROGRESS_FADE_END)); 199bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson } 200bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson 2015d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos private void updateSwipeProgressFromOffset(View animView, boolean dismissable) { 202bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson updateSwipeProgressFromOffset(animView, dismissable, getTranslation(animView)); 203bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson } 204bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson 205bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson private void updateSwipeProgressFromOffset(View animView, boolean dismissable, 206bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson float translation) { 207bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson float swipeProgress = getSwipeProgressForOffset(animView, translation); 2085d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) { 2095d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos if (FADE_OUT_DURING_SWIPE && dismissable) { 2105d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos float alpha = swipeProgress; 211671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson if (!mDisableHwLayers) { 212671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson if (alpha != 0f && alpha != 1f) { 213671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 214671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson } else { 215671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson animView.setLayerType(View.LAYER_TYPE_NONE, null); 216671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson } 2175d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos } 218bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson animView.setAlpha(getSwipeAlpha(swipeProgress)); 219499293f096ef3182ef39e42cc06284501022b5cfMichael Jurka } 22067b03701b633c293fd960435cd97fc0835e44568Michael Jurka } 22167b03701b633c293fd960435cd97fc0835e44568Michael Jurka invalidateGlobalRegion(animView); 22267b03701b633c293fd960435cd97fc0835e44568Michael Jurka } 22367b03701b633c293fd960435cd97fc0835e44568Michael Jurka 224a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler // invalidate the view's own bounds all the way up the view hierarchy 225a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public static void invalidateGlobalRegion(View view) { 226a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler invalidateGlobalRegion( 227a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler view, 228a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler new RectF(view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); 229a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 230a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 231a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler // invalidate a rectangle relative to the view's coordinate system all the way up the view 232a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler // hierarchy 233a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public static void invalidateGlobalRegion(View view, RectF childBounds) { 23496f4818ef41141649337d4dee09f837594e93d09Daniel Sandler //childBounds.offset(view.getTranslationX(), view.getTranslationY()); 23507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka if (DEBUG_INVALIDATE) 23607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka Log.v(TAG, "-------------"); 23707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka while (view.getParent() != null && view.getParent() instanceof View) { 23807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka view = (View) view.getParent(); 23907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka view.getMatrix().mapRect(childBounds); 24007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka view.invalidate((int) Math.floor(childBounds.left), 24107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka (int) Math.floor(childBounds.top), 24207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka (int) Math.ceil(childBounds.right), 24307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka (int) Math.ceil(childBounds.bottom)); 24407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka if (DEBUG_INVALIDATE) { 24507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka Log.v(TAG, "INVALIDATE(" + (int) Math.floor(childBounds.left) 24607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka + "," + (int) Math.floor(childBounds.top) 24707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka + "," + (int) Math.ceil(childBounds.right) 24807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka + "," + (int) Math.ceil(childBounds.bottom)); 24907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 25007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 25107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 25207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 253469e96e206f8df44b32ce393f8d19f0cae730030Daniel Sandler public void removeLongPressCallback() { 254f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler if (mWatchLongPress != null) { 255f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler mHandler.removeCallbacks(mWatchLongPress); 256491d3a9bfab844bf8587545bb1cdab76d2cd4b96Daniel Sandler mWatchLongPress = null; 257f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 258f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 259f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler 26043c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor @Override 2614247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler public boolean onInterceptTouchEvent(final MotionEvent ev) { 26207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka final int action = ev.getAction(); 26307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 26407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka switch (action) { 26507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka case MotionEvent.ACTION_DOWN: 26619c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek mTouchAboveFalsingThreshold = false; 26707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mDragging = false; 26830637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mSnappingChild = false; 269f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler mLongPressSent = false; 27007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mVelocityTracker.clear(); 2714b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor mCurrView = mCallback.getChildAtPosition(ev); 2724b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor 27321ce2d8caeda3c9eb762a2129d37c384de718941Michael Jurka if (mCurrView != null) { 27495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor onDownUpdate(mCurrView, ev); 27521ce2d8caeda3c9eb762a2129d37c384de718941Michael Jurka mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView); 27621ce2d8caeda3c9eb762a2129d37c384de718941Michael Jurka mVelocityTracker.addMovement(ev); 27721ce2d8caeda3c9eb762a2129d37c384de718941Michael Jurka mInitialTouchPos = getPos(ev); 2789b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi mPerpendicularInitialTouchPos = getPerpendicularPos(ev); 2794b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor mTranslation = getTranslation(mCurrView); 280f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler if (mLongPressListener != null) { 281f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler if (mWatchLongPress == null) { 282f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler mWatchLongPress = new Runnable() { 283f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler @Override 284f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler public void run() { 285197823da52a44422890667e21c17c28ab76e64b7Selim Cinek if (mCurrView != null && !mLongPressSent) { 286f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler mLongPressSent = true; 2874247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler mCurrView.sendAccessibilityEvent( 2884247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); 2894247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler mCurrView.getLocationOnScreen(mTmpPos); 2904247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler final int x = (int) ev.getRawX() - mTmpPos[0]; 2914247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler final int y = (int) ev.getRawY() - mTmpPos[1]; 29295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor MenuItem menuItem = null; 29395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor if (mCurrView instanceof ExpandableNotificationRow) { 29495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor menuItem = ((ExpandableNotificationRow) mCurrView) 29595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor .getProvider().getLongpressMenuItem(mContext); 29695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor } 29795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor mLongPressListener.onLongPress(mCurrView, x, y, menuItem); 298f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 299f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 300f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler }; 301f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 302469e96e206f8df44b32ce393f8d19f0cae730030Daniel Sandler mHandler.postDelayed(mWatchLongPress, mLongPressTimeout); 303f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 30421ce2d8caeda3c9eb762a2129d37c384de718941Michael Jurka } 30507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka break; 306f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler 30707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka case MotionEvent.ACTION_MOVE: 308f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler if (mCurrView != null && !mLongPressSent) { 30907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mVelocityTracker.addMovement(ev); 31007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka float pos = getPos(ev); 3119b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi float perpendicularPos = getPerpendicularPos(ev); 31207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka float delta = pos - mInitialTouchPos; 3139b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi float deltaPerpendicular = perpendicularPos - mPerpendicularInitialTouchPos; 3149b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi if (Math.abs(delta) > mPagingTouchSlop 3159b0a2c921a9268b89f3e72866b0f011749454c71Jorim Jaggi && Math.abs(delta) > Math.abs(deltaPerpendicular)) { 31607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mCallback.onBeginDrag(mCurrView); 31707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mDragging = true; 3184b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor mInitialTouchPos = getPos(ev); 3194b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor mTranslation = getTranslation(mCurrView); 320f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler removeLongPressCallback(); 32107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 32207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 32307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka break; 324f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler 32507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka case MotionEvent.ACTION_UP: 32668ebcdf3fd8b98fe35ec3e0b2e91fd254fcd807fJeff Brown case MotionEvent.ACTION_CANCEL: 3274247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler final boolean captured = (mDragging || mLongPressSent); 32807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mDragging = false; 32907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mCurrView = null; 330f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler mLongPressSent = false; 331491d3a9bfab844bf8587545bb1cdab76d2cd4b96Daniel Sandler removeLongPressCallback(); 3324247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler if (captured) return true; 33307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka break; 33407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 3354247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler return mDragging || mLongPressSent; 33607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 33707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 3382f2022afa1eb85018368398bd150e9575fc099c9Chet Haase /** 3392f2022afa1eb85018368398bd150e9575fc099c9Chet Haase * @param view The view to be dismissed 3402f2022afa1eb85018368398bd150e9575fc099c9Chet Haase * @param velocity The desired pixels/second speed at which the view should move 341dc6c97df483fb353ff6e18eb9ed59870c1101be8Mady Mellor * @param useAccelerateInterpolator Should an accelerating Interpolator be used 3422f2022afa1eb85018368398bd150e9575fc099c9Chet Haase */ 343dc6c97df483fb353ff6e18eb9ed59870c1101be8Mady Mellor public void dismissChild(final View view, float velocity, boolean useAccelerateInterpolator) { 344287963146c96a4cd2772cfee829ac4a4a03c1ff7Mady Mellor dismissChild(view, velocity, null /* endAction */, 0 /* delay */, 3459c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor useAccelerateInterpolator, 0 /* fixedDuration */, false /* isDismissAll */); 346eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler } 347eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler 348eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler /** 349eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler * @param view The view to be dismissed 350eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler * @param velocity The desired pixels/second speed at which the view should move 351eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler * @param endAction The action to perform at the end 352eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler * @param delay The delay after which we should start 353eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler * @param useAccelerateInterpolator Should an accelerating Interpolator be used 354eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler * @param fixedDuration If not 0, this exact duration will be taken 355eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler */ 3564b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor public void dismissChild(final View animView, float velocity, final Runnable endAction, 3579c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor long delay, boolean useAccelerateInterpolator, long fixedDuration, 3589c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor boolean isDismissAll) { 3594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor final boolean canBeDismissed = mCallback.canChildBeDismissed(animView); 36007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka float newPos; 3614b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; 362c6461ca5a0892d9b5a47649d49af69165e05b87fMichael Jurka 3639c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor // if we use the Menu to dismiss an item in landscape, animate up 3649c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor boolean animateUpForMenu = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll) 3659c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor && mSwipeDirection == Y; 3669c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor // if the language is rtl we prefer swiping to the left 3679c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor boolean animateLeftForRtl = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll) 3689c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor && isLayoutRtl; 3695574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) || 3705574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor (getTranslation(animView) < 0 && !isDismissAll); 3719c2c49634f0d457c1ab79772d3e817df629933dfMady Mellor if (animateLeft || animateLeftForRtl || animateUpForMenu) { 37207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka newPos = -getSize(animView); 37307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } else { 37407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka newPos = getSize(animView); 37507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 376eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler long duration; 377eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler if (fixedDuration == 0) { 378eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler duration = MAX_ESCAPE_ANIMATION_DURATION; 379eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler if (velocity != 0) { 380eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler duration = Math.min(duration, 381eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler (int) (Math.abs(newPos - getTranslation(animView)) * 1000f / Math 382eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler .abs(velocity)) 383eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler ); 384eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler } else { 385eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler duration = DEFAULT_ESCAPE_ANIMATION_DURATION; 386eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler } 3870e8063a3b447e1aa5cc3171db42f735b3b6ae78eMichael Jurka } else { 388eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler duration = fixedDuration; 38907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 3900e8063a3b447e1aa5cc3171db42f735b3b6ae78eMichael Jurka 391671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson if (!mDisableHwLayers) { 392671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 393671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson } 3944b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 39543c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor @Override 3964b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor public void onAnimationUpdate(ValueAnimator animation) { 3974b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed); 3984b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor } 3994b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor }; 4004b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor 4014b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor Animator anim = getViewTranslationAnimator(animView, newPos, updateListener); 40234958fa272c9216db4002546c3efad692b3d7775Mady Mellor if (anim == null) { 40334958fa272c9216db4002546c3efad692b3d7775Mady Mellor return; 40434958fa272c9216db4002546c3efad692b3d7775Mady Mellor } 405eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler if (useAccelerateInterpolator) { 406c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN); 407287963146c96a4cd2772cfee829ac4a4a03c1ff7Mady Mellor anim.setDuration(duration); 408eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler } else { 409287963146c96a4cd2772cfee829ac4a4a03c1ff7Mady Mellor mFlingAnimationUtils.applyDismissing(anim, getTranslation(animView), 410287963146c96a4cd2772cfee829ac4a4a03c1ff7Mady Mellor newPos, velocity, getSize(animView)); 411eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler } 412eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler if (delay > 0) { 413eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler anim.setStartDelay(delay); 414eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler } 4152f2022afa1eb85018368398bd150e9575fc099c9Chet Haase anim.addListener(new AnimatorListenerAdapter() { 41630637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan private boolean mCancelled; 41730637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan 41843c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor @Override 41930637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan public void onAnimationCancel(Animator animation) { 42030637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mCancelled = true; 42130637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 42230637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan 42343c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor @Override 42407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public void onAnimationEnd(Animator animation) { 4254b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor updateSwipeProgressFromOffset(animView, canBeDismissed); 42630637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mDismissPendingMap.remove(animView); 42730637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan if (!mCancelled) { 42830637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mCallback.onChildDismissed(animView); 42930637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 430eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler if (endAction != null) { 431eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler endAction.run(); 432eceda3d83814e20cabddc4f0755d475fa2f3d8ffDan Sandler } 433671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson if (!mDisableHwLayers) { 434671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson animView.setLayerType(View.LAYER_TYPE_NONE, null); 435671e8f91aae080dc66a0136ce1fc1c1ae0a90db4Winson } 43607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 43707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka }); 43830637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan 4398aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson prepareDismissAnimation(animView, anim); 44030637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mDismissPendingMap.put(animView, anim); 44107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka anim.start(); 44207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 44307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 4448aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson /** 4458aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson * Called to update the dismiss animation. 4468aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson */ 4478aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson protected void prepareDismissAnimation(View view, Animator anim) { 4488aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson // Do nothing 4498aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson } 4508aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson 4514b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor public void snapChild(final View animView, final float targetLeft, float velocity) { 4524b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor final boolean canBeDismissed = mCallback.canChildBeDismissed(animView); 4534b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor AnimatorUpdateListener updateListener = new AnimatorUpdateListener() { 45443c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor @Override 45507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public void onAnimationUpdate(ValueAnimator animation) { 4564b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed); 45767b03701b633c293fd960435cd97fc0835e44568Michael Jurka } 4584b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor }; 4594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor 4604b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener); 46134958fa272c9216db4002546c3efad692b3d7775Mady Mellor if (anim == null) { 46234958fa272c9216db4002546c3efad692b3d7775Mady Mellor return; 46334958fa272c9216db4002546c3efad692b3d7775Mady Mellor } 4644b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor int duration = SNAP_ANIM_LEN; 4654b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor anim.setDuration(duration); 46667b03701b633c293fd960435cd97fc0835e44568Michael Jurka anim.addListener(new AnimatorListenerAdapter() { 4677a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor boolean wasCancelled = false; 4687a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor 4697a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor @Override 4707a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor public void onAnimationCancel(Animator animator) { 4717a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor wasCancelled = true; 4727a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor } 4737a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor 47443c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor @Override 47567b03701b633c293fd960435cd97fc0835e44568Michael Jurka public void onAnimationEnd(Animator animator) { 47630637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mSnappingChild = false; 4777a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor if (!wasCancelled) { 4787a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor updateSwipeProgressFromOffset(animView, canBeDismissed); 4797a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor mCallback.onChildSnappedBack(animView, targetLeft); 4807a5b2b6d382cd8f9a081989ceab7a63ce9eee4d0Mady Mellor } 48107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 48207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka }); 4838aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson prepareSnapBackAnimation(animView, anim); 48430637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mSnappingChild = true; 48507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka anim.start(); 48607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 48707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 488c5fd350522d9269e6239af818f7261a6ead51570Winson /** 489c5fd350522d9269e6239af818f7261a6ead51570Winson * Called to update the snap back animation. 490c5fd350522d9269e6239af818f7261a6ead51570Winson */ 4918aa9959413a06c3d2ff75e0c7be9e3cb7ac7cd2eWinson protected void prepareSnapBackAnimation(View view, Animator anim) { 492c5fd350522d9269e6239af818f7261a6ead51570Winson // Do nothing 493c5fd350522d9269e6239af818f7261a6ead51570Winson } 494c5fd350522d9269e6239af818f7261a6ead51570Winson 4954b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor /** 4964b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * Called when there's a down event. 4974b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor */ 49895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor public void onDownUpdate(View currView, MotionEvent ev) { 4994b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor // Do nothing 5004b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor } 5014b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor 5024b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor /** 5034b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * Called on a move event. 5044b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor */ 50595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor protected void onMoveUpdate(View view, MotionEvent ev, float totalTranslation, float delta) { 5064b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor // Do nothing 5074b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor } 5084b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor 5094b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor /** 5104b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * Called in {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)} when the current 5114b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * view is being animated to dismiss or snap. 5124b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor */ 5134b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) { 514bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson updateSwipeProgressFromOffset(animView, canBeDismissed, value); 5154b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor } 5164b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor 51730637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan private void snapChildInstantly(final View view) { 51830637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view); 51930637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan setTranslation(view, 0); 52030637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan updateSwipeProgressFromOffset(view, canAnimViewBeDismissed); 52130637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 52230637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan 52386889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor /** 52486889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor * Called when a view is updated to be non-dismissable, if the view was being dismissed before 52586889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor * the update this will handle snapping it back into place. 52686889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor * 52786889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor * @param view the view to snap if necessary. 52886889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor * @param animate whether to animate the snap or not. 52986889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor * @param targetLeft the target to snap to. 53086889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor */ 53186889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor public void snapChildIfNeeded(final View view, boolean animate, float targetLeft) { 53230637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan if ((mDragging && mCurrView == view) || mSnappingChild) { 53330637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan return; 53430637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 53530637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan boolean needToSnap = false; 53630637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan Animator dismissPendingAnim = mDismissPendingMap.get(view); 53730637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan if (dismissPendingAnim != null) { 53830637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan needToSnap = true; 53930637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan dismissPendingAnim.cancel(); 54030637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } else if (getTranslation(view) != 0) { 54130637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan needToSnap = true; 54230637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 54330637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan if (needToSnap) { 54430637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan if (animate) { 54586889c2d21f4e6c26c7e07a477a9e5c398d5d059Mady Mellor snapChild(view, targetLeft, 0.0f /* velocity */); 54630637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } else { 54730637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan snapChildInstantly(view); 54830637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 54930637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 55030637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan } 55130637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan 55243c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor @Override 55307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public boolean onTouchEvent(MotionEvent ev) { 554f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler if (mLongPressSent) { 555f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler return true; 556f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler } 557f7a1956b06faeb6025fdea331f81d66edda58b3cDaniel Sandler 55807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka if (!mDragging) { 55928f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi if (mCallback.getChildAtPosition(ev) != null) { 56028f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi 56128f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi // We are dragging directly over a card, make sure that we also catch the gesture 56228f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi // even if nobody else wants the touch event. 56328f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi onInterceptTouchEvent(ev); 56428f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi return true; 56528f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi } else { 56628f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi 56728f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi // We are not doing anything, make sure the long press callback 56828f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi // is not still ticking like a bomb waiting to go off. 56928f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi removeLongPressCallback(); 57028f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi return false; 57128f0e5932944d9abc4b6879b1d05523e9341c385Jorim Jaggi } 57207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 57307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 57407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka mVelocityTracker.addMovement(ev); 57507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka final int action = ev.getAction(); 57607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka switch (action) { 57707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka case MotionEvent.ACTION_OUTSIDE: 57807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka case MotionEvent.ACTION_MOVE: 57907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka if (mCurrView != null) { 58007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka float delta = getPos(ev) - mInitialTouchPos; 58119c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek float absDelta = Math.abs(delta); 58234cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek if (absDelta >= getFalsingThreshold()) { 58319c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek mTouchAboveFalsingThreshold = true; 58419c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek } 58507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka // don't let items that can't be dismissed be dragged more than 58607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka // maxScrollDistance 58707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) { 5884b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor float size = getSize(mCurrView); 5895574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor float maxScrollDistance = MAX_SCROLL_SIZE_FRACTION * size; 59019c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek if (absDelta >= size) { 59107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka delta = delta > 0 ? maxScrollDistance : -maxScrollDistance; 59207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } else { 59307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2)); 59407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 59507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 59667b03701b633c293fd960435cd97fc0835e44568Michael Jurka 5974b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor setTranslation(mCurrView, mTranslation + delta); 5984b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor updateSwipeProgressFromOffset(mCurrView, mCanCurrViewBeDimissed); 59995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor onMoveUpdate(mCurrView, ev, mTranslation + delta, delta); 60007d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 60107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka break; 60207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka case MotionEvent.ACTION_UP: 60307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka case MotionEvent.ACTION_CANCEL: 6043a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor if (mCurrView == null) { 6053a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor break; 6063a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 6073a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, getMaxVelocity()); 6083a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor float velocity = getVelocity(mVelocityTracker); 60907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 6103a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor if (!handleUpEvent(ev, mCurrView, velocity, getTranslation(mCurrView))) { 6113a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor if (isDismissGesture(ev)) { 61207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka // flingadingy 613dc6c97df483fb353ff6e18eb9ed59870c1101be8Mady Mellor dismissChild(mCurrView, velocity, 614dc6c97df483fb353ff6e18eb9ed59870c1101be8Mady Mellor !swipedFastEnough() /* useAccelerateInterpolator */); 61507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } else { 61607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka // snappity 617622a97646d316ca753c577752ac9010415e9a472Peter Ng mCallback.onDragCancelled(mCurrView); 6184b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor snapChild(mCurrView, 0 /* leftTarget */, velocity); 61907d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 62030637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mCurrView = null; 62107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 62230637e41c9497576fa644c5ac0bf0864d3a52c5fdongwan mDragging = false; 62307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka break; 62407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 62507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka return true; 62607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 62707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 62834cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek private int getFalsingThreshold() { 62934cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek float factor = mCallback.getFalsingThresholdFactor(); 63034cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek return (int) (mFalsingThreshold * factor); 63134cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek } 63234cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek 6333a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor private float getMaxVelocity() { 6343a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor return MAX_DISMISS_VELOCITY * mDensityScale; 6353a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 6363a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor 6373a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor protected float getEscapeVelocity() { 638bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson return getUnscaledEscapeVelocity() * mDensityScale; 639bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson } 640bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson 641bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson protected float getUnscaledEscapeVelocity() { 642bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson return SWIPE_ESCAPE_VELOCITY; 643bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson } 644bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson 645bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson protected long getMaxEscapeAnimDuration() { 646bde852dbf5ba8c423da85aedfe6012ca67ee497cWinson return MAX_ESCAPE_ANIMATION_DURATION; 6473a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 6483a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor 6493a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor protected boolean swipedFarEnough() { 6503a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor float translation = getTranslation(mCurrView); 6515574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor return DISMISS_IF_SWIPED_FAR_ENOUGH 6525574425c32c75825004471434e0cd2fccdd4e5c0Mady Mellor && Math.abs(translation) > SWIPED_FAR_ENOUGH_SIZE_FRACTION * getSize(mCurrView); 6533a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 6543a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor 65595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor public boolean isDismissGesture(MotionEvent ev) { 656bd707492a2ef3641a9e9a64ef72b3b031dac0bb6Mady Mellor return ev.getActionMasked() == MotionEvent.ACTION_UP 657bd707492a2ef3641a9e9a64ef72b3b031dac0bb6Mady Mellor && !isFalseGesture(ev) && (swipedFastEnough() || swipedFarEnough()) 658bd707492a2ef3641a9e9a64ef72b3b031dac0bb6Mady Mellor && mCallback.canChildBeDismissed(mCurrView); 659bd707492a2ef3641a9e9a64ef72b3b031dac0bb6Mady Mellor } 660bd707492a2ef3641a9e9a64ef72b3b031dac0bb6Mady Mellor 661bd707492a2ef3641a9e9a64ef72b3b031dac0bb6Mady Mellor public boolean isFalseGesture(MotionEvent ev) { 6623a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor boolean falsingDetected = mCallback.isAntiFalsingNeeded(); 6633a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor if (mFalsingManager.isClassiferEnabled()) { 6643a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor falsingDetected = falsingDetected && mFalsingManager.isFalseTouch(); 6653a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } else { 6663a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor falsingDetected = falsingDetected && !mTouchAboveFalsingThreshold; 6673a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 668bd707492a2ef3641a9e9a64ef72b3b031dac0bb6Mady Mellor return falsingDetected; 6693a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 6703a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor 6713a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor protected boolean swipedFastEnough() { 6723a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor float velocity = getVelocity(mVelocityTracker); 6733a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor float translation = getTranslation(mCurrView); 674dc6c97df483fb353ff6e18eb9ed59870c1101be8Mady Mellor boolean ret = (Math.abs(velocity) > getEscapeVelocity()) 675dc6c97df483fb353ff6e18eb9ed59870c1101be8Mady Mellor && (velocity > 0) == (translation > 0); 6763a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor return ret; 6773a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 6783a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor 6793a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor protected boolean handleUpEvent(MotionEvent ev, View animView, float velocity, 6803a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor float translation) { 6813a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor return false; 6823a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor } 6833a5e8dd820ec6e85121857a03fe9c6a081455f43Mady Mellor 68407d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka public interface Callback { 68507d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka View getChildAtPosition(MotionEvent ev); 68607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 68707d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka boolean canChildBeDismissed(View v); 68807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 68919c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek boolean isAntiFalsingNeeded(); 69019c8c708f16546fc75ae12659aa190f5e3dfbb52Selim Cinek 69107d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka void onBeginDrag(View v); 69207d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka 69307d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka void onChildDismissed(View v); 694622a97646d316ca753c577752ac9010415e9a472Peter Ng 695622a97646d316ca753c577752ac9010415e9a472Peter Ng void onDragCancelled(View v); 696eb973565f3efc6417ca35363e4d6c642947775d8Selim Cinek 6974b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor /** 6984b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * Called when the child is snapped to a position. 6994b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * 7004b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * @param animView the view that was snapped. 7014b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor * @param targetLeft the left position the view was snapped to. 7024b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor */ 7034b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor void onChildSnappedBack(View animView, float targetLeft); 7045d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos 7055d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos /** 7065d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos * Updates the swipe progress on a child. 7075d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos * 7085d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos * @return if true, prevents the default alpha fading. 7095d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos */ 7105d9cc668e16abf1306d82218cd3da29e28a454aeAdrian Roos boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress); 71134cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek 71234cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek /** 71334cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek * @return The factor the falsing threshold should be multiplied with 71434cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek */ 71534cf5c4bfc7c4918b8155c47eb905782902016d6Selim Cinek float getFalsingThresholdFactor(); 71607d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka } 7174247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler 7184247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler /** 7194247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler * Equivalent to View.OnLongClickListener with coordinates 7204247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler */ 7214247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler public interface LongPressListener { 7224247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler /** 7234247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler * Equivalent to {@link View.OnLongClickListener#onLongClick(View)} with coordinates 7244247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler * @return whether the longpress was handled 7254247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler */ 72643c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor boolean onLongPress(View v, int x, int y, MenuItem item); 7274247a5c16237705c470b4dd7378a657c5f7b6d51Dan Sandler } 72807d4046ea914c999b7aaa587b7bfe81d548121f7Michael Jurka} 729