Loading quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +74 −50 Original line number Diff line number Diff line Loading @@ -208,14 +208,36 @@ import java.util.function.Supplier; private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) { AnimatorSet animatorSet = new AnimatorSet(); if (hasAnyFlag(changedFlags, FLAG_RESUMED)) { // Add the state animation first to ensure FLAG_IN_STASHED_LAUNCHER_STATE is set and we can // determine whether goingToUnstashedLauncherStateChanged. boolean wasGoingToUnstashedLauncherState = goingToUnstashedLauncherState(); if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) { boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING); playStateTransitionAnim(animatorSet, duration, committed); if (committed && mLauncherState == LauncherState.QUICK_SWITCH) { // We're about to be paused, set immediately to ensure seamless handoff. updateStateForFlag(FLAG_RESUMED, false); applyState(0 /* duration */); } } boolean goingToUnstashedLauncherStateChanged = wasGoingToUnstashedLauncherState != goingToUnstashedLauncherState(); boolean launcherStateChangedDuringAnimToResumeAlignment = mIconAlignmentForResumedState.isAnimating() && goingToUnstashedLauncherStateChanged; if (hasAnyFlag(changedFlags, FLAG_RESUMED) || launcherStateChangedDuringAnimToResumeAlignment) { boolean isResumed = isResumed(); ObjectAnimator anim = mIconAlignmentForResumedState .animateToValue(isResumed && goingToUnstashedLauncherState() ? 1 : 0) float toAlignmentForResumedState = isResumed && goingToUnstashedLauncherState() ? 1 : 0; // If we're already animating to the value, just leave it be instead of restarting it. if (!mIconAlignmentForResumedState.isAnimatingToValue(toAlignmentForResumedState)) { ObjectAnimator resumeAlignAnim = mIconAlignmentForResumedState .animateToValue(toAlignmentForResumedState) .setDuration(duration); anim.addListener(new AnimatorListenerAdapter() { resumeAlignAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIsAnimatingToLauncherViaResume = false; Loading @@ -225,23 +247,32 @@ import java.util.function.Supplier; public void onAnimationStart(Animator animation) { mIsAnimatingToLauncherViaResume = isResumed; TaskbarStashController stashController = mControllers.taskbarStashController; TaskbarStashController stashController = mControllers.taskbarStashController; stashController.updateStateForFlag(FLAG_IN_APP, !isResumed); stashController.applyState(duration); } }); animatorSet.play(anim); animatorSet.play(resumeAlignAnim); } } if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING)) { boolean launcherStateChangedDuringAnimToGestureAlignment = mIconAlignmentForGestureState.isAnimating() && goingToUnstashedLauncherStateChanged; if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING) || launcherStateChangedDuringAnimToGestureAlignment) { boolean isRecentsAnimationRunning = isRecentsAnimationRunning(); Animator animator = mIconAlignmentForGestureState .animateToValue(isRecentsAnimationRunning && goingToUnstashedLauncherState() ? 1 : 0); float toAlignmentForGestureState = isRecentsAnimationRunning && goingToUnstashedLauncherState() ? 1 : 0; // If we're already animating to the value, just leave it be instead of restarting it. if (!mIconAlignmentForGestureState.isAnimatingToValue(toAlignmentForGestureState)) { Animator gestureAlignAnim = mIconAlignmentForGestureState .animateToValue(toAlignmentForGestureState); if (isRecentsAnimationRunning) { animator.setDuration(duration); gestureAlignAnim.setDuration(duration); } animator.addListener(new AnimatorListenerAdapter() { gestureAlignAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIsAnimatingToLauncherViaGesture = false; Loading @@ -252,7 +283,8 @@ import java.util.function.Supplier; mIsAnimatingToLauncherViaGesture = isRecentsAnimationRunning(); } }); animatorSet.play(animator); animatorSet.play(gestureAlignAnim); } } if (hasAnyFlag(changedFlags, FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING)) { Loading @@ -265,17 +297,6 @@ import java.util.function.Supplier; .setDuration(duration)); } if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) { boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING); playStateTransitionAnim(animatorSet, duration, committed); if (committed && mLauncherState == LauncherState.QUICK_SWITCH) { // We're about to be paused, set immediately to ensure seamless handoff. updateStateForFlag(FLAG_RESUMED, false); applyState(0 /* duration */); } } if (start) { animatorSet.start(); } Loading Loading @@ -315,9 +336,12 @@ import java.util.function.Supplier; animatorSet.play(stashAnimator); } // If we're already animating to the value, just leave it be instead of restarting it. if (!mIconAlignmentForLauncherState.isAnimatingToValue(toAlignment)) { animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment) .setDuration(duration)); } } private boolean isResumed() { return (mState & FLAG_RESUMED) != 0; Loading quickstep/src/com/android/quickstep/AnimatedFloat.java +21 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class AnimatedFloat { private final Runnable mUpdateCallback; private ObjectAnimator mValueAnimator; // Only non-null when an animation is playing to this value. private Float mEndValue; public float value; Loading @@ -67,10 +69,18 @@ public class AnimatedFloat { cancelAnimation(); mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, start, end); mValueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animator) { if (mValueAnimator == animator) { mEndValue = end; } } @Override public void onAnimationEnd(Animator animator) { if (mValueAnimator == animator) { mValueAnimator = null; mEndValue = null; } } }); Loading Loading @@ -103,4 +113,15 @@ public class AnimatedFloat { public ObjectAnimator getCurrentAnimation() { return mValueAnimator; } public boolean isAnimating() { return mValueAnimator != null; } /** * Returns whether we are currently animating, and the animation's end value matches the given. */ public boolean isAnimatingToValue(float endValue) { return isAnimating() && mEndValue != null && mEndValue == endValue; } } Loading
quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +74 −50 Original line number Diff line number Diff line Loading @@ -208,14 +208,36 @@ import java.util.function.Supplier; private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) { AnimatorSet animatorSet = new AnimatorSet(); if (hasAnyFlag(changedFlags, FLAG_RESUMED)) { // Add the state animation first to ensure FLAG_IN_STASHED_LAUNCHER_STATE is set and we can // determine whether goingToUnstashedLauncherStateChanged. boolean wasGoingToUnstashedLauncherState = goingToUnstashedLauncherState(); if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) { boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING); playStateTransitionAnim(animatorSet, duration, committed); if (committed && mLauncherState == LauncherState.QUICK_SWITCH) { // We're about to be paused, set immediately to ensure seamless handoff. updateStateForFlag(FLAG_RESUMED, false); applyState(0 /* duration */); } } boolean goingToUnstashedLauncherStateChanged = wasGoingToUnstashedLauncherState != goingToUnstashedLauncherState(); boolean launcherStateChangedDuringAnimToResumeAlignment = mIconAlignmentForResumedState.isAnimating() && goingToUnstashedLauncherStateChanged; if (hasAnyFlag(changedFlags, FLAG_RESUMED) || launcherStateChangedDuringAnimToResumeAlignment) { boolean isResumed = isResumed(); ObjectAnimator anim = mIconAlignmentForResumedState .animateToValue(isResumed && goingToUnstashedLauncherState() ? 1 : 0) float toAlignmentForResumedState = isResumed && goingToUnstashedLauncherState() ? 1 : 0; // If we're already animating to the value, just leave it be instead of restarting it. if (!mIconAlignmentForResumedState.isAnimatingToValue(toAlignmentForResumedState)) { ObjectAnimator resumeAlignAnim = mIconAlignmentForResumedState .animateToValue(toAlignmentForResumedState) .setDuration(duration); anim.addListener(new AnimatorListenerAdapter() { resumeAlignAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIsAnimatingToLauncherViaResume = false; Loading @@ -225,23 +247,32 @@ import java.util.function.Supplier; public void onAnimationStart(Animator animation) { mIsAnimatingToLauncherViaResume = isResumed; TaskbarStashController stashController = mControllers.taskbarStashController; TaskbarStashController stashController = mControllers.taskbarStashController; stashController.updateStateForFlag(FLAG_IN_APP, !isResumed); stashController.applyState(duration); } }); animatorSet.play(anim); animatorSet.play(resumeAlignAnim); } } if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING)) { boolean launcherStateChangedDuringAnimToGestureAlignment = mIconAlignmentForGestureState.isAnimating() && goingToUnstashedLauncherStateChanged; if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING) || launcherStateChangedDuringAnimToGestureAlignment) { boolean isRecentsAnimationRunning = isRecentsAnimationRunning(); Animator animator = mIconAlignmentForGestureState .animateToValue(isRecentsAnimationRunning && goingToUnstashedLauncherState() ? 1 : 0); float toAlignmentForGestureState = isRecentsAnimationRunning && goingToUnstashedLauncherState() ? 1 : 0; // If we're already animating to the value, just leave it be instead of restarting it. if (!mIconAlignmentForGestureState.isAnimatingToValue(toAlignmentForGestureState)) { Animator gestureAlignAnim = mIconAlignmentForGestureState .animateToValue(toAlignmentForGestureState); if (isRecentsAnimationRunning) { animator.setDuration(duration); gestureAlignAnim.setDuration(duration); } animator.addListener(new AnimatorListenerAdapter() { gestureAlignAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIsAnimatingToLauncherViaGesture = false; Loading @@ -252,7 +283,8 @@ import java.util.function.Supplier; mIsAnimatingToLauncherViaGesture = isRecentsAnimationRunning(); } }); animatorSet.play(animator); animatorSet.play(gestureAlignAnim); } } if (hasAnyFlag(changedFlags, FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING)) { Loading @@ -265,17 +297,6 @@ import java.util.function.Supplier; .setDuration(duration)); } if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) { boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING); playStateTransitionAnim(animatorSet, duration, committed); if (committed && mLauncherState == LauncherState.QUICK_SWITCH) { // We're about to be paused, set immediately to ensure seamless handoff. updateStateForFlag(FLAG_RESUMED, false); applyState(0 /* duration */); } } if (start) { animatorSet.start(); } Loading Loading @@ -315,9 +336,12 @@ import java.util.function.Supplier; animatorSet.play(stashAnimator); } // If we're already animating to the value, just leave it be instead of restarting it. if (!mIconAlignmentForLauncherState.isAnimatingToValue(toAlignment)) { animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment) .setDuration(duration)); } } private boolean isResumed() { return (mState & FLAG_RESUMED) != 0; Loading
quickstep/src/com/android/quickstep/AnimatedFloat.java +21 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class AnimatedFloat { private final Runnable mUpdateCallback; private ObjectAnimator mValueAnimator; // Only non-null when an animation is playing to this value. private Float mEndValue; public float value; Loading @@ -67,10 +69,18 @@ public class AnimatedFloat { cancelAnimation(); mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, start, end); mValueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animator) { if (mValueAnimator == animator) { mEndValue = end; } } @Override public void onAnimationEnd(Animator animator) { if (mValueAnimator == animator) { mValueAnimator = null; mEndValue = null; } } }); Loading Loading @@ -103,4 +113,15 @@ public class AnimatedFloat { public ObjectAnimator getCurrentAnimation() { return mValueAnimator; } public boolean isAnimating() { return mValueAnimator != null; } /** * Returns whether we are currently animating, and the animation's end value matches the given. */ public boolean isAnimatingToValue(float endValue) { return isAnimating() && mEndValue != null && mEndValue == endValue; } }