Add tweaks to smooth out swipe to dismiss.

Bug: 34673753
Change-Id: I5a9d420c70d124fc764803d505291e66818b1aa2
(cherry picked from commit 2e11adaac3)
This commit is contained in:
Michael Kwan
2017-02-12 13:43:45 -08:00
parent 62314d7dd3
commit 5758a9a94c

View File

@@ -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;
}
}