diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 5a4b9f0952..9d10e1e0a9 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -16,9 +16,11 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.LauncherState.HOTSEAT_ICONS; +import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_SETUP; +import static com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_DURATION; import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME; import android.animation.Animator; @@ -38,6 +40,7 @@ import com.android.launcher3.QuickstepTransitionManager; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; +import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.InstanceIdSequence; @@ -55,6 +58,7 @@ import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.recents.model.ThumbnailData; import java.util.Arrays; +import java.util.function.Supplier; import java.util.stream.Stream; /** @@ -72,17 +76,64 @@ public class LauncherTaskbarUIController extends TaskbarUIController { new AnimatedFloat(this::onIconAlignmentRatioChanged); private final AnimatedFloat mIconAlignmentForGestureState = new AnimatedFloat(this::onIconAlignmentRatioChanged); + private final AnimatedFloat mIconAlignmentForLauncherState = + new AnimatedFloat(this::onIconAlignmentRatioChangedForStateTransition); private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener = this::onStashedInAppChanged; private final StateManager.StateListener mStateListener = new StateManager.StateListener() { + private Animator mAnimator; + + @Override + public void onStateTransitionStart(LauncherState toState) { + // Stash animation from going to launcher should be already handled in + // createAnimToLauncher. + TaskbarStashController controller = mControllers.taskbarStashController; + long duration = TASKBAR_STASH_DURATION; + controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, + toState.isTaskbarStashed()); + Animator stashAnimator = controller.applyStateWithoutStart(duration); + if (stashAnimator != null) { + if (mAnimator != null) { + mAnimator.cancel(); + } + PendingAnimation pendingAnimation = new PendingAnimation(duration); + pendingAnimation.add(stashAnimator); + pendingAnimation.setFloat(mIconAlignmentForLauncherState, + AnimatedFloat.VALUE, toState.isTaskbarStashed() ? 0 : 1, + FAST_OUT_SLOW_IN); + pendingAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animator) { + mTargetStateOverrideForStateTransition = toState; + // Copy hotseat alpha over to taskbar icons + mIconAlphaForHome.setValue(mLauncher.getHotseat().getIconsAlpha()); + mLauncher.getHotseat().setIconsAlpha(0); + } + + @Override + public void onAnimationEnd(Animator animator) { + if (toState.isTaskbarStashed()) { + // Reset hotseat alpha to default + mLauncher.getHotseat().setIconsAlpha(1); + } + mTargetStateOverrideForStateTransition = null; + mAnimator = null; + } + }); + mAnimator = pendingAnimation.buildAnim(); + mAnimator.start(); + } + } + @Override public void onStateTransitionComplete(LauncherState finalState) { TaskbarStashController controller = mControllers.taskbarStashController; controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, finalState.isTaskbarStashed()); + controller.applyState(); } }; @@ -96,6 +147,8 @@ public class LauncherTaskbarUIController extends TaskbarUIController { private TaskbarKeyguardController mKeyguardController; private LauncherState mTargetStateOverride = null; + private LauncherState mTargetStateOverrideForStateTransition = null; + private final DeviceProfile.OnDeviceProfileChangeListener mProfileChangeListener = new DeviceProfile.OnDeviceProfileChangeListener() { @Override @@ -144,6 +197,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController { onLauncherResumedOrPaused(false); mIconAlignmentForResumedState.finishAnimation(); mIconAlignmentForGestureState.finishAnimation(); + mIconAlignmentForLauncherState.finishAnimation(); mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener); mLauncher.getStateManager().removeStateListener(mStateListener); @@ -258,25 +312,35 @@ public class LauncherTaskbarUIController extends TaskbarUIController { return Math.max(mIconAlignmentForResumedState.value, mIconAlignmentForGestureState.value); } + private float getCurrentIconAlignmentRatioForLauncherState() { + return mIconAlignmentForLauncherState.value; + } + + private void onIconAlignmentRatioChangedForStateTransition() { + onIconAlignmentRatioChanged( + mTargetStateOverrideForStateTransition != null + ? mTargetStateOverrideForStateTransition + : mLauncher.getStateManager().getState(), + this::getCurrentIconAlignmentRatioForLauncherState); + } + private void onIconAlignmentRatioChanged() { + onIconAlignmentRatioChanged(mTargetStateOverride != null ? mTargetStateOverride + : mLauncher.getStateManager().getState(), this::getCurrentIconAlignmentRatio); + } + + private void onIconAlignmentRatioChanged(LauncherState state, + Supplier alignmentSupplier) { if (mControllers == null) { return; } - float alignment = getCurrentIconAlignmentRatio(); + float alignment = alignmentSupplier.get(); mControllers.taskbarViewController.setLauncherIconAlignment( alignment, mLauncher.getDeviceProfile()); mTaskbarBackgroundAlpha.updateValue(1 - alignment); - LauncherState state = mTargetStateOverride != null ? mTargetStateOverride - : mLauncher.getStateManager().getState(); - if ((state.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) { - // If the hotseat icons are visible, then switch taskbar in last frame - setTaskbarViewVisible(alignment < 1); - } else { - mLauncher.getHotseat().setIconsAlpha(1); - mIconAlphaForHome.setValue(1 - alignment); - } + setIconAlpha(state, alignment); } /** @@ -295,6 +359,15 @@ public class LauncherTaskbarUIController extends TaskbarUIController { return mTaskbarDragLayer; } + private void setIconAlpha(LauncherState state, float progress) { + if ((state.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) { + // If the hotseat icons are visible, then switch taskbar in last frame + setTaskbarViewVisible(progress < 1); + } else { + mIconAlphaForHome.setValue(1 - progress); + } + } + private void setTaskbarViewVisible(boolean isVisible) { mIconAlphaForHome.setValue(isVisible ? 1 : 0); mLauncher.getHotseat().setIconsAlpha(isVisible ? 0f : 1f); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 56c6f61513..7a892240e0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -63,7 +63,7 @@ public class TaskbarStashController { /** * How long to stash/unstash when manually invoked via long press. */ - private static final long TASKBAR_STASH_DURATION = 300; + public static final long TASKBAR_STASH_DURATION = 300; /** * The scale TaskbarView animates to when being stashed. @@ -279,7 +279,12 @@ public class TaskbarStashController { return false; } - private Animator createAnimToIsStashed(boolean isStashed, long duration) { + /** + * Create a stash animation and save to {@link #mAnimator}. + * @param isStashed whether it's a stash animation or an unstash animation + * @param duration duration of the animation + */ + private void createAnimToIsStashed(boolean isStashed, long duration) { if (mAnimator != null) { mAnimator.cancel(); } @@ -289,7 +294,7 @@ public class TaskbarStashController { // Just hide/show the icons instead of stashing into a handle. mAnimator.play(mIconAlphaForStash.animateToValue(isStashed ? 0 : 1) .setDuration(duration)); - return mAnimator; + return; } AnimatorSet fullLengthAnimatorSet = new AnimatorSet(); @@ -361,7 +366,6 @@ public class TaskbarStashController { mAnimator = null; } }); - return mAnimator; } /** @@ -481,12 +485,13 @@ public class TaskbarStashController { boolean isStashed = mStashCondition.test(flags); if (mIsStashed != isStashed) { mIsStashed = isStashed; - Animator animator = createAnimToIsStashed(mIsStashed, duration); + createAnimToIsStashed(mIsStashed, duration); if (start) { - animator.start(); + mAnimator.start(); } + return mAnimator; } - return mAnimator; + return null; } } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java index f8c9fd128f..c554fd0a91 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java @@ -68,6 +68,11 @@ public class AllAppsState extends LauncherState { return scaleAndTranslation; } + @Override + public boolean isTaskbarStashed() { + return true; + } + @Override protected float getDepthUnchecked(Context context) { // The scrim fades in at approximately 50% of the swipe gesture. diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index e86c02cb01..ffe38168ac 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -198,6 +198,10 @@ public class Hotseat extends CellLayout implements Insettable { getShortcutsAndWidgets().setAlpha(alpha); } + public float getIconsAlpha() { + return getShortcutsAndWidgets().getAlpha(); + } + /** * Returns the QSB inside hotseat */