diff options
author | 2025-03-06 22:13:23 +0000 | |
---|---|---|
committer | 2025-03-07 15:47:48 -0500 | |
commit | 26f9468db19930881cf484247e769a3b51136d23 (patch) | |
tree | 071ff150123cc6ebac4d93d4efcc3fbc4df85d59 | |
parent | 16020c58a94d0063c2abf725fa07d005f43b8169 (diff) |
Animate changes in Taskbar recents indicators.
Flag: com.android.window.flags.enable_taskbar_recents_layout_transition
Fix: 356394053
Test: go/testedequals
Change-Id: Ic018695254bbfea11469c3579e242089b00b90f5
-rw-r--r-- | quickstep/res/values/dimens.xml | 1 | ||||
-rw-r--r-- | quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java | 20 | ||||
-rw-r--r-- | res/values/dimens.xml | 1 | ||||
-rw-r--r-- | src/com/android/launcher3/BubbleTextView.java | 105 |
4 files changed, 112 insertions, 15 deletions
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 6196be42fa..36e6902972 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -371,7 +371,6 @@ <dimen name="taskbar_running_app_indicator_height">2dp</dimen> <dimen name="taskbar_running_app_indicator_width">12dp</dimen> <dimen name="taskbar_running_app_indicator_top_margin">4dp</dimen> - <dimen name="taskbar_minimized_app_indicator_width">6dp</dimen> <!-- Transient taskbar --> <dimen name="transient_taskbar_padding">12dp</dimen> diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 0fe022460c..a80e2c4365 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -24,6 +24,7 @@ import static android.window.DesktopModeFlags.ENABLE_TASKBAR_RECENTS_LAYOUT_TRAN import static com.android.app.animation.Interpolators.EMPHASIZED; import static com.android.app.animation.Interpolators.FINAL_FRAME; import static com.android.app.animation.Interpolators.LINEAR; +import static com.android.launcher3.BubbleTextView.LINE_INDICATOR_ANIM_DURATION; import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation; import static com.android.launcher3.Flags.taskbarOverflow; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; @@ -138,6 +139,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar private static final int TRANSITION_DEFAULT_DURATION = 500; private static final int TRANSITION_FADE_IN_DURATION = 167; private static final int TRANSITION_FADE_OUT_DURATION = 83; + private static final int APPEARING_LINE_INDICATOR_ANIM_DELAY = + TRANSITION_DEFAULT_DURATION - LINE_INDICATOR_ANIM_DURATION; private final TaskbarActivityContext mActivity; private @Nullable TaskbarDragLayerController mDragLayerController; @@ -736,7 +739,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar public void updateIconViewsRunningStates() { for (View iconView : getIconViews()) { if (iconView instanceof BubbleTextView btv) { - btv.updateRunningState(getRunningAppState(btv)); + updateRunningState(btv); if (shouldUpdateIconContentDescription(btv)) { btv.setContentDescription( btv.getContentDescription() + " " + btv.getIconStateDescription()); @@ -770,6 +773,10 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar return pinnedAppsWithTasks; } + private void updateRunningState(BubbleTextView btv) { + btv.updateRunningState(getRunningAppState(btv), mTaskbarView.getLayoutTransition() != null); + } + private BubbleTextView.RunningAppState getRunningAppState(BubbleTextView btv) { Object tag = btv.getTag(); if (tag instanceof TaskItemInfo itemInfo) { @@ -1225,13 +1232,22 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar view.setAlpha(0f); view.setScaleX(0f); view.setScaleY(0f); + if (view instanceof BubbleTextView btv) { + // Defer so that app is mostly scaled in before showing indicator. + btv.setLineIndicatorAnimStartDelay(APPEARING_LINE_INDICATOR_ANIM_DELAY); + } + } else if (type == DISAPPEARING && view instanceof BubbleTextView btv) { + // Running state updates happen after removing this view, so update it here. + updateRunningState(btv); } } @Override public void endTransition( LayoutTransition transition, ViewGroup container, View view, int type) { - // Do nothing. + if (type == APPEARING && view instanceof BubbleTextView btv) { + btv.setLineIndicatorAnimStartDelay(0); + } } }); diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 64f67cd4b4..a15c130076 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -445,7 +445,6 @@ <dimen name="taskbar_running_app_indicator_height">0dp</dimen> <dimen name="taskbar_running_app_indicator_width">0dp</dimen> <dimen name="taskbar_running_app_indicator_top_margin">0dp</dimen> - <dimen name="taskbar_minimized_app_indicator_width">0dp</dimen> <!-- Transient taskbar (placeholders to compile in Launcher3 without Quickstep) --> <dimen name="transient_taskbar_padding">0dp</dimen> diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 7b656d7372..783e82cae9 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -20,6 +20,7 @@ import static android.graphics.fonts.FontStyle.FONT_WEIGHT_BOLD; import static android.graphics.fonts.FontStyle.FONT_WEIGHT_NORMAL; import static android.text.Layout.Alignment.ALIGN_NORMAL; +import static com.android.app.animation.Interpolators.EMPHASIZED; import static com.android.launcher3.BubbleTextView.RunningAppState.RUNNING; import static com.android.launcher3.BubbleTextView.RunningAppState.NOT_RUNNING; import static com.android.launcher3.BubbleTextView.RunningAppState.MINIMIZED; @@ -37,6 +38,7 @@ import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SHOW_DOWNLO import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.ColorStateList; @@ -130,6 +132,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, StringMatcherUtility.StringMatcher.getInstance(); private static final int BOLD_TEXT_ADJUSTMENT = FONT_WEIGHT_BOLD - FONT_WEIGHT_NORMAL; + public static final int LINE_INDICATOR_ANIM_DURATION = 150; + private static final float MINIMIZED_APP_INDICATOR_SCALE = 0.5f; + private static final int[] STATE_PRESSED = new int[]{android.R.attr.state_pressed}; private float mScaleForReorderBounce = 1f; @@ -165,6 +170,36 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, } }; + private static final Property<BubbleTextView, Integer> LINE_INDICATOR_COLOR_PROPERTY = + new Property<>(Integer.class, "lineIndicatorColor") { + + @Override + public Integer get(BubbleTextView bubbleTextView) { + return bubbleTextView.mLineIndicatorColor; + } + + @Override + public void set(BubbleTextView bubbleTextView, Integer color) { + bubbleTextView.mLineIndicatorColor = color; + bubbleTextView.invalidate(); + } + }; + + private static final Property<BubbleTextView, Float> LINE_INDICATOR_SCALE_PROPERTY = + new Property<>(Float.TYPE, "lineIndicatorScale") { + + @Override + public Float get(BubbleTextView bubbleTextView) { + return bubbleTextView.mLineIndicatorScale; + } + + @Override + public void set(BubbleTextView bubbleTextView, Float scale) { + bubbleTextView.mLineIndicatorScale = scale; + bubbleTextView.invalidate(); + } + }; + private final MultiTranslateDelegate mTranslateDelegate = new MultiTranslateDelegate(this); protected final ActivityContext mActivity; private FastBitmapDrawable mIcon; @@ -202,7 +237,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, // These fields, related to showing running apps, are only used for Taskbar. private final int mRunningAppIndicatorWidth; - private final int mMinimizedAppIndicatorWidth; private final int mRunningAppIndicatorHeight; private final int mRunningAppIndicatorTopMargin; private final Paint mRunningAppIndicatorPaint; @@ -210,6 +244,12 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, private RunningAppState mRunningAppState; private final int mRunningAppIndicatorColor; private final int mMinimizedAppIndicatorColor; + @ViewDebug.ExportedProperty(category = "launcher") + private int mLineIndicatorColor; + @ViewDebug.ExportedProperty(category = "launcher") + private float mLineIndicatorScale; + private int mLineIndicatorAnimStartDelay; + private Animator mLineIndicatorAnim; private final String mMinimizedStateDescription; private final String mRunningStateDescription; @@ -294,8 +334,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mRunningAppIndicatorWidth = getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_width); - mMinimizedAppIndicatorWidth = - getResources().getDimensionPixelSize(R.dimen.taskbar_minimized_app_indicator_width); mRunningAppIndicatorHeight = getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_height); mRunningAppIndicatorTopMargin = @@ -344,6 +382,11 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mForceHideDot = false; setBackground(null); + mLineIndicatorColor = Color.TRANSPARENT; + mLineIndicatorScale = 0; + mLineIndicatorAnimStartDelay = 0; + cancelLineIndicatorAnim(); + setTag(null); if (mIconLoadRequest != null) { mIconLoadRequest.cancel(); @@ -436,9 +479,50 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, /** Updates whether the app this view represents is currently running. */ @UiThread - public void updateRunningState(RunningAppState runningAppState) { + public void updateRunningState(RunningAppState runningAppState, boolean animate) { + if (runningAppState.equals(mRunningAppState)) { + return; + } mRunningAppState = runningAppState; - invalidate(); + cancelLineIndicatorAnim(); + + int color = switch (mRunningAppState) { + case NOT_RUNNING -> Color.TRANSPARENT; + case RUNNING -> mRunningAppIndicatorColor; + case MINIMIZED -> mMinimizedAppIndicatorColor; + }; + float scale = switch (mRunningAppState) { + case NOT_RUNNING -> 0; + case RUNNING -> 1; + case MINIMIZED -> MINIMIZED_APP_INDICATOR_SCALE; + }; + + if (!animate) { + mLineIndicatorColor = color; + mLineIndicatorScale = scale; + invalidate(); + return; + } + + AnimatorSet lineIndicatorAnim = new AnimatorSet(); + mLineIndicatorAnim = lineIndicatorAnim; + Animator colorAnimator = ObjectAnimator.ofArgb(this, LINE_INDICATOR_COLOR_PROPERTY, color); + Animator scaleAnimator = ObjectAnimator.ofFloat(this, LINE_INDICATOR_SCALE_PROPERTY, scale); + lineIndicatorAnim.playTogether(colorAnimator, scaleAnimator); + + lineIndicatorAnim.setInterpolator(EMPHASIZED); + lineIndicatorAnim.setStartDelay(mLineIndicatorAnimStartDelay); + lineIndicatorAnim.setDuration(LINE_INDICATOR_ANIM_DURATION).start(); + } + + public void setLineIndicatorAnimStartDelay(int lineIndicatorAnimStartDelay) { + mLineIndicatorAnimStartDelay = lineIndicatorAnimStartDelay; + } + + private void cancelLineIndicatorAnim() { + if (mLineIndicatorAnim != null) { + mLineIndicatorAnim.cancel(); + } } /** @@ -790,19 +874,18 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, /** Draws a line under the app icon if this is representing a running app in Desktop Mode. */ protected void drawRunningAppIndicatorIfNecessary(Canvas canvas) { - if (mRunningAppState == NOT_RUNNING || mDisplay != DISPLAY_TASKBAR) { + if (mDisplay != DISPLAY_TASKBAR + || mLineIndicatorScale == 0 + || mLineIndicatorColor == Color.TRANSPARENT) { return; } getIconBounds(mRunningAppIconBounds); Utilities.scaleRectAboutCenter(mRunningAppIconBounds, ICON_VISIBLE_AREA_FACTOR); - final boolean isMinimized = mRunningAppState == MINIMIZED; final int indicatorTop = mRunningAppIconBounds.bottom + mRunningAppIndicatorTopMargin; - final int indicatorWidth = - isMinimized ? mMinimizedAppIndicatorWidth : mRunningAppIndicatorWidth; + final float indicatorWidth = mRunningAppIndicatorWidth * mLineIndicatorScale; final float cornerRadius = mRunningAppIndicatorHeight / 2f; - mRunningAppIndicatorPaint.setColor( - isMinimized ? mMinimizedAppIndicatorColor : mRunningAppIndicatorColor); + mRunningAppIndicatorPaint.setColor(mLineIndicatorColor); canvas.drawRoundRect( mRunningAppIconBounds.centerX() - indicatorWidth / 2f, |