diff options
author | Michael Kwan <mkwan@google.com> | 2017-02-12 13:43:45 -0800 |
---|---|---|
committer | Michael Kwan <mkwan@google.com> | 2017-02-13 06:17:06 +0000 |
commit | 5758a9a94c7ca1a196b3d1c51b05ec2d937f0b59 (patch) | |
tree | d431a55491503073c5cacf0752d9e70c2b635b3a | |
parent | 62314d7dd33e86b935f9dea13c160177995a992c (diff) | |
download | base-5758a9a94c7ca1a196b3d1c51b05ec2d937f0b59.tar.gz |
Add tweaks to smooth out swipe to dismiss.
Bug: 34673753
Change-Id: I5a9d420c70d124fc764803d505291e66818b1aa2
(cherry picked from commit 2e11adaac3ec959044e8154c67b6ab9cde82fdab)
-rw-r--r-- | core/java/com/android/internal/widget/SwipeDismissLayout.java | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java index 2a5957ce0ca2..261fa4327494 100644 --- a/core/java/com/android/internal/widget/SwipeDismissLayout.java +++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java @@ -43,7 +43,8 @@ import android.widget.FrameLayout; public class SwipeDismissLayout extends FrameLayout { private static final String TAG = "SwipeDismissLayout"; - private static final float DISMISS_MIN_DRAG_WIDTH_RATIO = .33f; + private static final float MAX_DIST_THRESHOLD = .33f; + private static final float MIN_DIST_THRESHOLD = .1f; public interface OnDismissedListener { void onDismissed(SwipeDismissLayout layout); @@ -73,6 +74,7 @@ public class SwipeDismissLayout extends FrameLayout { private int mActiveTouchId; private float mDownX; private float mDownY; + private float mLastX; private boolean mSwiping; private boolean mDismissed; private boolean mDiscardIntercept; @@ -105,7 +107,6 @@ public class SwipeDismissLayout extends FrameLayout { }; private IntentFilter mScreenOffFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); - private float mLastX; private boolean mDismissable = true; @@ -174,7 +175,7 @@ public class SwipeDismissLayout extends FrameLayout { mDownX = ev.getRawX(); mDownY = ev.getRawY(); mActiveTouchId = ev.getPointerId(0); - mVelocityTracker = VelocityTracker.obtain(); + mVelocityTracker = VelocityTracker.obtain("int1"); mVelocityTracker.addMovement(ev); break; @@ -238,7 +239,10 @@ public class SwipeDismissLayout extends FrameLayout { updateDismiss(ev); if (mDismissed) { mDismissAnimator.animateDismissal(ev.getRawX() - mDownX); - } else if (mSwiping) { + } else if (mSwiping + // Only trigger animation if we had a MOVE event that would shift the + // underlying view, otherwise the animation would be janky. + && mLastX != Integer.MIN_VALUE) { mDismissAnimator.animateRecovery(ev.getRawX() - mDownX); } resetMembers(); @@ -298,6 +302,7 @@ public class SwipeDismissLayout extends FrameLayout { mVelocityTracker = null; mTranslationX = 0; mDownX = 0; + mLastX = Integer.MIN_VALUE; mDownY = 0; mSwiping = false; mDismissed = false; @@ -329,19 +334,32 @@ public class SwipeDismissLayout extends FrameLayout { private void updateDismiss(MotionEvent ev) { float deltaX = ev.getRawX() - mDownX; - mVelocityTracker.addMovement(ev); + // Don't add the motion event as an UP event would clear the velocity tracker mVelocityTracker.computeCurrentVelocity(1000); + float xVelocity = mVelocityTracker.getXVelocity(); + if (mLastX == Integer.MIN_VALUE) { + // If there's no changes to mLastX, we have only one point of data, and therefore no + // velocity. Estimate velocity from just the up and down event in that case. + xVelocity = deltaX / ((ev.getEventTime() - ev.getDownTime()) / 1000); + } if (!mDismissed) { - if ((deltaX > (getWidth() * DISMISS_MIN_DRAG_WIDTH_RATIO) && - ev.getRawX() >= mLastX) - || mVelocityTracker.getXVelocity() >= mMinFlingVelocity) { + // Adjust the distance threshold linearly between the min and max threshold based on the + // x-velocity scaled with the the fling threshold speed + float distanceThreshold = getWidth() * Math.max( + Math.min((MIN_DIST_THRESHOLD - MAX_DIST_THRESHOLD) + * xVelocity / mMinFlingVelocity // scale x-velocity with fling velocity + + MAX_DIST_THRESHOLD, // offset to start at max threshold + MAX_DIST_THRESHOLD), // cap at max threshold + MIN_DIST_THRESHOLD); // bottom out at min threshold + if ((deltaX > distanceThreshold && ev.getRawX() >= mLastX) + || xVelocity >= mMinFlingVelocity) { mDismissed = true; } } // Check if the user tried to undo this. if (mDismissed && mSwiping) { // Check if the user's finger is actually flinging back to left - if (mVelocityTracker.getXVelocity() < -mMinFlingVelocity) { + if (xVelocity < -mMinFlingVelocity) { mDismissed = false; } } |