diff options
Diffstat (limited to 'src/com/android/launcher3/anim/AnimatorPlaybackController.java')
-rw-r--r-- | src/com/android/launcher3/anim/AnimatorPlaybackController.java | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java index 819c8439b..62f59e402 100644 --- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java +++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java @@ -16,6 +16,7 @@ package com.android.launcher3.anim; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; import android.animation.Animator; import android.animation.Animator.AnimatorListener; @@ -23,10 +24,16 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; +import android.util.Log; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; + +import androidx.dynamicanimation.animation.DynamicAnimation; +import androidx.dynamicanimation.animation.SpringAnimation; /** * Helper class to control the playback of an {@link AnimatorSet}, with custom interpolators @@ -37,6 +44,9 @@ import java.util.List; */ public abstract class AnimatorPlaybackController implements ValueAnimator.AnimatorUpdateListener { + private static final String TAG = "AnimatorPlaybackCtrler"; + private static boolean DEBUG = false; + public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration) { return wrap(anim, duration, null); } @@ -60,6 +70,7 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat private final long mDuration; protected final AnimatorSet mAnim; + private Set<SpringAnimation> mSprings; protected float mCurrentFraction; private Runnable mEndAction; @@ -67,6 +78,9 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat protected boolean mTargetCancelled = false; protected Runnable mOnCancelRunnable; + private OnAnimationEndDispatcher mEndListener; + private DynamicAnimation.OnAnimationEndListener mSpringEndListener; + protected AnimatorPlaybackController(AnimatorSet anim, long duration, Runnable onCancelRunnable) { mAnim = anim; @@ -75,7 +89,8 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat mAnimationPlayer = ValueAnimator.ofFloat(0, 1); mAnimationPlayer.setInterpolator(LINEAR); - mAnimationPlayer.addListener(new OnAnimationEndDispatcher()); + mEndListener = new OnAnimationEndDispatcher(); + mAnimationPlayer.addListener(mEndListener); mAnimationPlayer.addUpdateListener(this); mAnim.addListener(new AnimatorListenerAdapter() { @@ -99,6 +114,15 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat mTargetCancelled = false; } }); + + mSprings = new HashSet<>(); + mSpringEndListener = (animation, canceled, value, velocity1) -> { + if (canceled) { + mEndListener.onAnimationCancel(mAnimationPlayer); + } else { + mEndListener.onAnimationEnd(mAnimationPlayer); + } + }; } public AnimatorSet getTarget() { @@ -180,6 +204,29 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat } } + /** + * Starts playback and sets the spring. + */ + public void dispatchOnStartWithVelocity(float end, float velocity) { + if (!QUICKSTEP_SPRINGS.get()) { + dispatchOnStart(); + return; + } + + if (DEBUG) Log.d(TAG, "dispatchOnStartWithVelocity#end=" + end + ", velocity=" + velocity); + + for (Animator a : mAnim.getChildAnimations()) { + if (a instanceof SpringObjectAnimator) { + if (DEBUG) Log.d(TAG, "Found springAnimator=" + a); + SpringObjectAnimator springAnimator = (SpringObjectAnimator) a; + mSprings.add(springAnimator.getSpring()); + springAnimator.startSpring(end, velocity, mSpringEndListener); + } + } + + dispatchOnStart(); + } + public void dispatchOnStart() { dispatchOnStartRecursively(mAnim); } @@ -282,6 +329,18 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat } } + private boolean isAnySpringRunning() { + for (SpringAnimation spring : mSprings) { + if (spring.isRunning()) { + return true; + } + } + return false; + } + + /** + * Only dispatches the on end actions once the animator and all springs have completed running. + */ private class OnAnimationEndDispatcher extends AnimationSuccessListener { @Override @@ -291,9 +350,12 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat @Override public void onAnimationSuccess(Animator animator) { - dispatchOnEndRecursively(mAnim); - if (mEndAction != null) { - mEndAction.run(); + // We wait for the spring (if any) to finish running before completing the end callback. + if (mSprings.isEmpty() || !isAnySpringRunning()) { + dispatchOnEndRecursively(mAnim); + if (mEndAction != null) { + mEndAction.run(); + } } } |