summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Kwan <mkwan@google.com>2017-02-12 13:43:45 -0800
committerMichael Kwan <mkwan@google.com>2017-02-13 06:17:06 +0000
commit5758a9a94c7ca1a196b3d1c51b05ec2d937f0b59 (patch)
treed431a55491503073c5cacf0752d9e70c2b635b3a
parent62314d7dd33e86b935f9dea13c160177995a992c (diff)
downloadbase-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.java36
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;
}
}