Merge "Update screenshot dismiss gesture physics" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
24658c8bdf
@@ -861,11 +861,15 @@ public class ScreenshotView extends FrameLayout implements
|
|||||||
|
|
||||||
class SwipeDismissHandler implements OnTouchListener {
|
class SwipeDismissHandler implements OnTouchListener {
|
||||||
// distance needed to register a dismissal
|
// distance needed to register a dismissal
|
||||||
private static final float DISMISS_DISTANCE_THRESHOLD_DP = 30;
|
private static final float DISMISS_DISTANCE_THRESHOLD_DP = 20;
|
||||||
|
|
||||||
private final GestureDetector mGestureDetector;
|
private final GestureDetector mGestureDetector;
|
||||||
|
|
||||||
private float mStartX;
|
private float mStartX;
|
||||||
|
// Keeps track of the most recent direction (between the last two move events).
|
||||||
|
// -1 for left; +1 for right.
|
||||||
|
private int mDirectionX;
|
||||||
|
private float mPreviousX;
|
||||||
|
|
||||||
SwipeDismissHandler() {
|
SwipeDismissHandler() {
|
||||||
GestureDetector.OnGestureListener gestureListener = new SwipeDismissGestureListener();
|
GestureDetector.OnGestureListener gestureListener = new SwipeDismissGestureListener();
|
||||||
@@ -878,6 +882,7 @@ public class ScreenshotView extends FrameLayout implements
|
|||||||
mCallbacks.onUserInteraction();
|
mCallbacks.onUserInteraction();
|
||||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||||
mStartX = event.getRawX();
|
mStartX = event.getRawX();
|
||||||
|
mPreviousX = mStartX;
|
||||||
return true;
|
return true;
|
||||||
} else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
|
} else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
|
||||||
if (isPastDismissThreshold()
|
if (isPastDismissThreshold()
|
||||||
@@ -906,16 +911,42 @@ public class ScreenshotView extends FrameLayout implements
|
|||||||
public boolean onScroll(
|
public boolean onScroll(
|
||||||
MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
|
MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
|
||||||
mScreenshotStatic.setTranslationX(ev2.getRawX() - mStartX);
|
mScreenshotStatic.setTranslationX(ev2.getRawX() - mStartX);
|
||||||
|
mDirectionX = (ev2.getRawX() < mPreviousX) ? -1 : 1;
|
||||||
|
mPreviousX = ev2.getRawX();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||||
|
float velocityY) {
|
||||||
|
if (mScreenshotStatic.getTranslationX() * velocityX > 0
|
||||||
|
&& (mDismissAnimation == null || !mDismissAnimation.isRunning())) {
|
||||||
|
animateDismissal(createSwipeDismissAnimation(velocityX / (float) 1000));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPastDismissThreshold() {
|
private boolean isPastDismissThreshold() {
|
||||||
float distance = Math.abs(mScreenshotStatic.getTranslationX());
|
float translationX = mScreenshotStatic.getTranslationX();
|
||||||
return distance >= dpToPx(DISMISS_DISTANCE_THRESHOLD_DP);
|
// Determines whether the absolute translation from the start is in the same direction
|
||||||
|
// as the current movement. For example, if the user moves most of the way to the right,
|
||||||
|
// but then starts dragging back left, we do not dismiss even though the absolute
|
||||||
|
// distance is greater than the threshold.
|
||||||
|
if (translationX * mDirectionX > 0) {
|
||||||
|
return Math.abs(translationX) >= dpToPx(DISMISS_DISTANCE_THRESHOLD_DP);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueAnimator createSwipeDismissAnimation() {
|
private ValueAnimator createSwipeDismissAnimation() {
|
||||||
|
return createSwipeDismissAnimation(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValueAnimator createSwipeDismissAnimation(float velocity) {
|
||||||
|
// velocity is measured in pixels per millisecond
|
||||||
|
velocity = Math.min(3, Math.max(1, velocity));
|
||||||
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
|
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
|
||||||
float startX = mScreenshotStatic.getTranslationX();
|
float startX = mScreenshotStatic.getTranslationX();
|
||||||
// make sure the UI gets all the way off the screen in the direction of movement
|
// make sure the UI gets all the way off the screen in the direction of movement
|
||||||
@@ -924,13 +955,14 @@ public class ScreenshotView extends FrameLayout implements
|
|||||||
float finalX = startX < 0
|
float finalX = startX < 0
|
||||||
? -1 * mActionsContainerBackground.getRight()
|
? -1 * mActionsContainerBackground.getRight()
|
||||||
: mDisplayMetrics.widthPixels;
|
: mDisplayMetrics.widthPixels;
|
||||||
|
float distance = Math.abs(finalX - startX);
|
||||||
|
|
||||||
anim.addUpdateListener(animation -> {
|
anim.addUpdateListener(animation -> {
|
||||||
float translation = MathUtils.lerp(startX, finalX, animation.getAnimatedFraction());
|
float translation = MathUtils.lerp(startX, finalX, animation.getAnimatedFraction());
|
||||||
mScreenshotStatic.setTranslationX(translation);
|
mScreenshotStatic.setTranslationX(translation);
|
||||||
setAlpha(1 - animation.getAnimatedFraction());
|
setAlpha(1 - animation.getAnimatedFraction());
|
||||||
});
|
});
|
||||||
anim.setDuration(400);
|
anim.setDuration((long) (distance / Math.abs(velocity)));
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user