Merge "Taskbar motion polish to keep icons within taskbar bg bounds." into tm-qpr-dev am: 8a53e78f22 am: 9c2a40576e am: c5d3518763

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/22133846

Change-Id: Id459968dcb188c1df971c58e74862aa7d8b8e4df
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jon Miranda
2023-03-20 19:48:00 +00:00
committed by Automerger Merge Worker
2 changed files with 63 additions and 37 deletions
@@ -39,7 +39,6 @@ import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.window.RefreshRateTracker;
import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.RecentsView;
@@ -67,6 +66,10 @@ import java.util.StringJoiner;
/** Equivalent to an int with all 1s for binary operation purposes */ /** Equivalent to an int with all 1s for binary operation purposes */
private static final int FLAGS_ALL = ~0; private static final int FLAGS_ALL = ~0;
private static final float TASKBAR_BG_ALPHA_LAUNCHER_NOT_ALIGNED_DELAY_MULT = 0.33f;
private static final float TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT = 0.33f;
private static final float TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT = 0.25f;
private final AnimatedFloat mIconAlignment = private final AnimatedFloat mIconAlignment =
new AnimatedFloat(this::onIconAlignmentRatioChanged); new AnimatedFloat(this::onIconAlignmentRatioChanged);
@@ -274,7 +277,8 @@ import java.util.StringJoiner;
private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) { private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) {
final boolean goingToLauncher = isInLauncher(); final boolean goingToLauncher = isInLauncher();
final float toAlignment = isIconAlignedWithHotseat() ? 1 : 0; final boolean isIconAlignedWithHotseat = isIconAlignedWithHotseat();
final float toAlignment = isIconAlignedWithHotseat ? 1 : 0;
boolean handleOpenFloatingViews = false; boolean handleOpenFloatingViews = false;
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onStateChangeApplied - mState: " + getStateString(mState) Log.d(TAG, "onStateChangeApplied - mState: " + getStateString(mState)
@@ -343,15 +347,29 @@ import java.util.StringJoiner;
+ " -> " + backgroundAlpha + ": " + duration); + " -> " + backgroundAlpha + ": " + duration);
} }
boolean goingToLauncherIconNotAligned = goingToLauncher && !isIconAlignedWithHotseat;
boolean notGoingToLauncherIconNotAligned = !goingToLauncher
&& !isIconAlignedWithHotseat;
boolean goingToLauncherIconIsAligned = goingToLauncher && isIconAlignedWithHotseat;
float startDelay = 0;
// We want to delay the background from fading in so that the icons have time to move
// into the bounds of the background before it appears.
if (goingToLauncherIconNotAligned) {
startDelay = duration * TASKBAR_BG_ALPHA_LAUNCHER_NOT_ALIGNED_DELAY_MULT;
} else if (notGoingToLauncherIconNotAligned) {
startDelay = duration * TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT;
}
float newDuration = duration - startDelay;
if (goingToLauncherIconIsAligned) {
// Make the background fade out faster so that it is gone by the time the
// icons move outside of the bounds of the background.
newDuration = duration * TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT;
}
Animator taskbarBackgroundAlpha = mTaskbarBackgroundAlpha Animator taskbarBackgroundAlpha = mTaskbarBackgroundAlpha
.animateToValue(backgroundAlpha) .animateToValue(backgroundAlpha)
.setDuration(duration); .setDuration((long) newDuration);
// Add a single frame delay to the taskbar bg to avoid too many moving parts during the taskbarBackgroundAlpha.setStartDelay((long) startDelay);
// app launch animation.
taskbarBackgroundAlpha.setStartDelay(
(hasAnyFlag(changedFlags, FLAG_RESUMED) && !goingToLauncher)
? RefreshRateTracker.getSingleFrameMs(mLauncher)
: 0);
animatorSet.play(taskbarBackgroundAlpha); animatorSet.play(taskbarBackgroundAlpha);
} }
@@ -90,9 +90,6 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
public static final int ALPHA_INDEX_SMALL_SCREEN = 6; public static final int ALPHA_INDEX_SMALL_SCREEN = 6;
private static final int NUM_ALPHA_CHANNELS = 7; private static final int NUM_ALPHA_CHANNELS = 7;
// This allows the icons on the edge to stay within the taskbar background bounds.
private static final float ICON_REVEAL_X_DURATION_MULTIPLIER = 0.8f;
private static final float TASKBAR_DARK_THEME_ICONS_BACKGROUND_LUMINANCE = 0.30f; private static final float TASKBAR_DARK_THEME_ICONS_BACKGROUND_LUMINANCE = 0.30f;
private final TaskbarActivityContext mActivity; private final TaskbarActivityContext mActivity;
@@ -134,6 +131,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
private final DeviceProfile.OnDeviceProfileChangeListener mDeviceProfileChangeListener = private final DeviceProfile.OnDeviceProfileChangeListener mDeviceProfileChangeListener =
dp -> commitRunningAppsToUI(); dp -> commitRunningAppsToUI();
private final boolean mIsRtl;
public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) { public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
mActivity = activity; mActivity = activity;
mTaskbarView = taskbarView; mTaskbarView = taskbarView;
@@ -180,6 +179,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
}, VERTICAL); }, VERTICAL);
mSwipeDownDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false); mSwipeDownDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false);
} }
mIsRtl = Utilities.isRtl(mTaskbarView.getResources());
} }
public void init(TaskbarControllers controllers) { public void init(TaskbarControllers controllers) {
@@ -309,18 +309,34 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
)); ));
} }
private ValueAnimator createRevealAnimForView(View view, boolean isStashed) { private ValueAnimator createRevealAnimForView(View view, boolean isStashed, float newWidth,
boolean shouldStartAlign) {
Rect viewBounds = new Rect(0, 0, view.getWidth(), view.getHeight()); Rect viewBounds = new Rect(0, 0, view.getWidth(), view.getHeight());
int centerY = viewBounds.centerY(); int centerY = viewBounds.centerY();
int halfHandleHeight = mStashedHandleHeight / 2; int halfHandleHeight = mStashedHandleHeight / 2;
final int top = centerY - halfHandleHeight;
final int bottom = centerY + halfHandleHeight;
Rect stashedRect = new Rect(viewBounds.left, final int left;
centerY - halfHandleHeight, final int right;
viewBounds.right, if (shouldStartAlign) {
centerY + halfHandleHeight); if (mIsRtl) {
right = viewBounds.right;
left = (int) (right - newWidth);
} else {
left = viewBounds.left;
right = (int) (left + newWidth);
}
} else {
int widthDelta = (int) ((viewBounds.width() - newWidth) / 2);
left = viewBounds.left + widthDelta;
right = viewBounds.right - widthDelta;
}
Rect stashedRect = new Rect(left, top, right, bottom);
float radius = 0; float radius = 0;
float stashedRadius = viewBounds.width() / 2f; float stashedRadius = stashedRect.width() / 2f;
return new RoundedRectRevealOutlineProvider(radius, stashedRadius, viewBounds, stashedRect) return new RoundedRectRevealOutlineProvider(radius, stashedRadius, viewBounds, stashedRect)
.createRevealAnimator(view, !isStashed, 0); .createRevealAnimator(view, !isStashed, 0);
@@ -342,44 +358,36 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
Rect stashedBounds = new Rect(); Rect stashedBounds = new Rect();
mControllers.stashedHandleViewController.getStashedHandleBounds(stashedBounds); mControllers.stashedHandleViewController.getStashedHandleBounds(stashedBounds);
boolean isQsbInline = mActivity.getDeviceProfile().isQsbInline; int numIcons = mTaskbarView.getChildCount();
int numIcons = mTaskbarView.getChildCount() - (isQsbInline ? 1 : 0); float newChildWidth = stashedBounds.width() / (float) numIcons;
// We do not actually modify the width of the icons, but we will use this width to position
// the children to overlay the nav handle.
float virtualChildWidth = stashedBounds.width() / (float) numIcons;
// All children move the same y-amount since they will be cropped to the same centerY. // All children move the same y-amount since they will be cropped to the same centerY.
float croppedTransY = mTaskbarView.getIconTouchSize() - stashedBounds.height(); float croppedTransY = mTaskbarView.getIconTouchSize() - stashedBounds.height();
boolean isRtl = Utilities.isRtl(mTaskbarView.getResources());
for (int i = mTaskbarView.getChildCount() - 1; i >= 0; i--) { for (int i = mTaskbarView.getChildCount() - 1; i >= 0; i--) {
View child = mTaskbarView.getChildAt(i); View child = mTaskbarView.getChildAt(i);
boolean isQsb = child == mTaskbarView.getQsb(); boolean isQsb = child == mTaskbarView.getQsb();
// Crop the icons to/from the nav handle shape. // Crop the icons to/from the nav handle shape.
reveal.play(createRevealAnimForView(child, isStashed).setDuration(duration)); reveal.play(createRevealAnimForView(child, isStashed, newChildWidth, isQsb)
.setDuration(duration));
// Translate the icons to/from their locations as the "nav handle." // Translate the icons to/from their locations as the "nav handle."
// We look at 'left' and 'right' values to ensure that the children stay within the
// bounds of the stashed handle.
// All of the Taskbar icons will overlap the entirety of the stashed handle // All of the Taskbar icons will overlap the entirety of the stashed handle
// And the QSB, if inline, will overlap part of stashed handle as well. // And the QSB, if inline, will overlap part of stashed handle as well.
int positionInHandle = (isQsbInline && !isQsb)
? i + (isRtl ? 1 : -1)
: i;
float currentPosition = isQsb ? child.getX() : child.getLeft(); float currentPosition = isQsb ? child.getX() : child.getLeft();
float newPosition = stashedBounds.left + (virtualChildWidth * positionInHandle); float newPosition = stashedBounds.left + (newChildWidth * i);
final float croppedTransX; final float croppedTransX;
// We look at 'left' and 'right' values to ensure that the children stay within the
// bounds of the stashed handle since the new width only occurs at the end of the anim.
if (currentPosition > newPosition) { if (currentPosition > newPosition) {
float newRight = stashedBounds.right - (virtualChildWidth float newRight = stashedBounds.right - (newChildWidth
* (numIcons - 1 - positionInHandle)); * (numIcons - 1 - i));
croppedTransX = -(currentPosition + child.getWidth() - newRight); croppedTransX = -(currentPosition + child.getWidth() - newRight);
} else { } else {
croppedTransX = newPosition - currentPosition; croppedTransX = newPosition - currentPosition;
} }
long transXDuration = (long) (duration * ICON_REVEAL_X_DURATION_MULTIPLIER);
float[] transX = isStashed float[] transX = isStashed
? new float[] {croppedTransX} ? new float[] {croppedTransX}
: new float[] {croppedTransX, 0}; : new float[] {croppedTransX, 0};
@@ -392,14 +400,14 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM), reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM),
MULTI_PROPERTY_VALUE, transX) MULTI_PROPERTY_VALUE, transX)
.setDuration(transXDuration)); .setDuration(duration));
reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM), reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
MULTI_PROPERTY_VALUE, transY)); MULTI_PROPERTY_VALUE, transY));
as.addListener(forEndCallback(() -> as.addListener(forEndCallback(() ->
mtd.setTranslation(INDEX_TASKBAR_REVEAL_ANIM, 0, 0))); mtd.setTranslation(INDEX_TASKBAR_REVEAL_ANIM, 0, 0)));
} else { } else {
reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_X, transX) reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_X, transX)
.setDuration(transXDuration)); .setDuration(duration));
reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_Y, transY)); reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_Y, transY));
as.addListener(forEndCallback(() -> { as.addListener(forEndCallback(() -> {
child.setTranslationX(0); child.setTranslationX(0);