summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Brian Isganitis <brianji@google.com> 2025-03-06 22:13:23 +0000
committer Brian Isganitis <brianji@google.com> 2025-03-07 15:47:48 -0500
commit26f9468db19930881cf484247e769a3b51136d23 (patch)
tree071ff150123cc6ebac4d93d4efcc3fbc4df85d59
parent16020c58a94d0063c2abf725fa07d005f43b8169 (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.xml1
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java20
-rw-r--r--res/values/dimens.xml1
-rw-r--r--src/com/android/launcher3/BubbleTextView.java105
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,