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
This commit is contained in:
Fabian Kozynski
2022-03-21 16:10:19 -04:00
parent edbe5bf307
commit 5bac374167

View File

@@ -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();
}
}
}