diff options
| -rw-r--r-- | core/java/android/window/BackEvent.java | 16 | ||||
| -rw-r--r-- | core/java/android/window/BackProgressAnimator.java | 23 | ||||
| -rw-r--r-- | core/java/android/window/WindowOnBackInvokedDispatcher.java | 11 |
3 files changed, 44 insertions, 6 deletions
diff --git a/core/java/android/window/BackEvent.java b/core/java/android/window/BackEvent.java index 4a4f561c71ed..940b133eb169 100644 --- a/core/java/android/window/BackEvent.java +++ b/core/java/android/window/BackEvent.java @@ -99,7 +99,21 @@ public class BackEvent implements Parcelable { } /** - * Returns a value between 0 and 1 on how far along the back gesture is. + * Returns a value between 0 and 1 on how far along the back gesture is. This value is + * driven by the horizontal location of the touch point, and should be used as the fraction to + * seek the predictive back animation with. Specifically, + * <ol> + * <li>The progress is 0 when the touch is at the starting edge of the screen (left or right), + * and animation should seek to its start state. + * <li>The progress is approximately 1 when the touch is at the opposite side of the screen, + * and animation should seek to its end state. Exact end value may vary depending on + * screen size. + * </ol> + * <li> After the gesture finishes in cancel state, this method keeps getting invoked until the + * progress value animates back to 0. + * </ol> + * In-between locations are linearly interpolated based on horizontal distance from the starting + * edge and smooth clamped to 1 when the distance exceeds a system-wide threshold. */ public float getProgress() { return mProgress; diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java index 38c52e7473f1..b22f967e9e2a 100644 --- a/core/java/android/window/BackProgressAnimator.java +++ b/core/java/android/window/BackProgressAnimator.java @@ -16,8 +16,10 @@ package android.window; +import android.annotation.NonNull; import android.util.FloatProperty; +import com.android.internal.dynamicanimation.animation.DynamicAnimation; import com.android.internal.dynamicanimation.animation.SpringAnimation; import com.android.internal.dynamicanimation.animation.SpringForce; @@ -123,6 +125,27 @@ public class BackProgressAnimator { mProgress = 0; } + /** + * Animate the back progress animation from current progress to start position. + * This should be called when back is cancelled. + * + * @param finishCallback the callback to be invoked when the progress is reach to 0. + */ + public void onBackCancelled(@NonNull Runnable finishCallback) { + final DynamicAnimation.OnAnimationEndListener listener = + new DynamicAnimation.OnAnimationEndListener() { + @Override + public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, + float velocity) { + mSpring.removeEndListener(this); + finishCallback.run(); + reset(); + } + }; + mSpring.addEndListener(listener); + mSpring.animateToFinalPosition(0); + } + private void updateProgressValue(float progress) { if (mLastBackEvent == null || mCallback == null || !mStarted) { return; diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java index dd9483a9c759..bfa3447076d5 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -255,11 +255,12 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { @Override public void onBackCancelled() { Handler.getMain().post(() -> { - mProgressAnimator.reset(); - final OnBackAnimationCallback callback = getBackAnimationCallback(); - if (callback != null) { - callback.onBackCancelled(); - } + mProgressAnimator.onBackCancelled(() -> { + final OnBackAnimationCallback callback = getBackAnimationCallback(); + if (callback != null) { + callback.onBackCancelled(); + } + }); }); } |