From 5bac374167166be8d10063c5d4d14db14413fa2b Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Mon, 21 Mar 2022 16:10:19 -0400 Subject: [PATCH] Fix icon color animator The animation for the icon color change in QS assumed that the colors were grayscale (leftover from the old tiles). Since the colors are not necessarily grayscale, animate using an ArgbEvaluator. Fixes: 225043591 Test: manual Change-Id: I85a05f31704651fbf953efa44bde71f741574916 --- .../systemui/qs/tileimpl/QSIconViewImpl.java | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java index 7fb9ef34cfd1d..be6982ab2470f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -16,13 +16,14 @@ package com.android.systemui.qs.tileimpl; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.ArgbEvaluator; +import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.annotation.Nullable; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.Color; import android.graphics.drawable.Animatable2; import android.graphics.drawable.Animatable2.AnimationCallback; import android.graphics.drawable.Drawable; @@ -53,6 +54,8 @@ public class QSIconViewImpl extends QSIconView { @Nullable private QSTile.Icon mLastIcon; + private ValueAnimator mColorAnimator = new ValueAnimator(); + public QSIconViewImpl(Context context) { super(context); @@ -61,6 +64,7 @@ public class QSIconViewImpl extends QSIconView { mIcon = createIcon(); addView(mIcon); + mColorAnimator.setDuration(QS_ANIM_LENGTH); } @Override @@ -165,7 +169,6 @@ public class QSIconViewImpl extends QSIconView { mState = state.state; if (mTint != 0 && allowAnimations && shouldAnimate(iv)) { animateGrayScale(mTint, color, iv, () -> updateIcon(iv, state, allowAnimations)); - mTint = color; } else { if (iv instanceof AlphaControlledSlashImageView) { ((AlphaControlledSlashImageView)iv) @@ -173,7 +176,6 @@ public class QSIconViewImpl extends QSIconView { } else { setTint(iv, color); } - mTint = color; updateIcon(iv, state, allowAnimations); } } else { @@ -191,39 +193,30 @@ public class QSIconViewImpl extends QSIconView { ((AlphaControlledSlashImageView)iv) .setFinalImageTintList(ColorStateList.valueOf(toColor)); } + mColorAnimator.cancel(); if (mAnimationEnabled && ValueAnimator.areAnimatorsEnabled()) { - final float fromAlpha = Color.alpha(fromColor); - final float toAlpha = Color.alpha(toColor); - final float fromChannel = Color.red(fromColor); - final float toChannel = Color.red(toColor); - - ValueAnimator anim = ValueAnimator.ofFloat(0, 1); - anim.setDuration(QS_ANIM_LENGTH); - anim.addUpdateListener(animation -> { - float fraction = animation.getAnimatedFraction(); - int alpha = (int) (fromAlpha + (toAlpha - fromAlpha) * fraction); - int channel = (int) (fromChannel + (toChannel - fromChannel) * fraction); - - setTint(iv, Color.argb(alpha, channel, channel, channel)); + PropertyValuesHolder values = PropertyValuesHolder.ofInt("color", fromColor, toColor); + values.setEvaluator(ArgbEvaluator.getInstance()); + mColorAnimator.setValues(values); + mColorAnimator.removeAllListeners(); + mColorAnimator.addUpdateListener(animation -> { + setTint(iv, (int) animation.getAnimatedValue()); }); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - endRunnable.run(); - } - }); - anim.start(); + mColorAnimator.addListener(new EndRunnableAnimatorListener(endRunnable)); + + mColorAnimator.start(); } else { + setTint(iv, toColor); endRunnable.run(); } } - public static void setTint(ImageView iv, int color) { + public void setTint(ImageView iv, int color) { iv.setImageTintList(ColorStateList.valueOf(color)); + mTint = color; } - protected int getIconMeasureMode() { return MeasureSpec.EXACTLY; } @@ -261,4 +254,25 @@ public class QSIconViewImpl extends QSIconView { return 0; } } + + private static class EndRunnableAnimatorListener extends AnimatorListenerAdapter { + private Runnable mRunnable; + + EndRunnableAnimatorListener(Runnable endRunnable) { + super(); + mRunnable = endRunnable; + } + + @Override + public void onAnimationCancel(Animator animation) { + super.onAnimationCancel(animation); + mRunnable.run(); + } + + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + mRunnable.run(); + } + } }