Android:ValueAnimator颜色切换过快?如何实现平滑缓慢过渡?
Hey there! Let's tackle that jittery, too-fast color transition on your logo animation. I see a couple of key issues in your code that are causing the problem, and fixing them will get you that smooth, slow color shift you want.
First: You're using resource IDs instead of actual color values
The ValueAnimator.ofArgb() method expects raw ARGB integer values (like 0xFFFF0000 for red), but you're passing in R.color.xxx which are just resource reference IDs (not the actual color data). This makes the animator calculate transitions incorrectly, leading to unexpected speed and flickering.
Fix this by resolving the color resources to their actual integer values first. Use ContextCompat.getColor() for better compatibility across Android versions:
int colorGold = ContextCompat.getColor(this, R.color.colorGoldNew); int colorDb0 = ContextCompat.getColor(this, R.color.dbIndex0); int colorDb5 = ContextCompat.getColor(this, R.color.dbIndex5); int colorDb6 = ContextCompat.getColor(this, R.color.dbIndex6);
Second: Add a smooth interpolator
By default, the animator uses a linear interpolator, which can make transitions feel abrupt. Adding an AccelerateDecelerateInterpolator will make the animation start slowly, speed up in the middle, and slow down at the end—creating a much more natural, smooth effect.
Third: Explicitly set the color filter mode
Sometimes flickering happens because the color filter isn't applied consistently. Specifying a PorterDuff.Mode (like SRC_IN) ensures the color is applied correctly over your logo.
Here's your revised code
private void animateLogo(){ ImageView imgLogo = findViewById(R.id.imgview_logo); // Resolve color resources to actual ARGB values int colorGold = ContextCompat.getColor(this, R.color.colorGoldNew); int colorDb0 = ContextCompat.getColor(this, R.color.dbIndex0); int colorDb5 = ContextCompat.getColor(this, R.color.dbIndex5); int colorDb6 = ContextCompat.getColor(this, R.color.dbIndex6); ValueAnimator animator = ValueAnimator.ofArgb(colorGold, colorDb0, colorDb5, colorDb6); animator.setDuration(5000); // Keep your 5-second duration animator.setEvaluator(new ArgbEvaluator()); // Add the smooth interpolator animator.setInterpolator(new AccelerateDecelerateInterpolator()); animator.addUpdateListener(animation -> { int currentColor = (int) animation.getAnimatedValue(); // Apply color filter with explicit mode imgLogo.setColorFilter(currentColor, PorterDuff.Mode.SRC_IN); }); animator.start(); }
Bonus: Simplify with ObjectAnimator
If you want cleaner code, you can use ObjectAnimator which directly binds to the colorFilter property of your ImageView. It handles the update logic internally, which can also help reduce any potential flickering:
private void animateLogo(){ ImageView imgLogo = findViewById(R.id.imgview_logo); int colorGold = ContextCompat.getColor(this, R.color.colorGoldNew); int colorDb0 = ContextCompat.getColor(this, R.color.dbIndex0); int colorDb5 = ContextCompat.getColor(this, R.color.dbIndex5); int colorDb6 = ContextCompat.getColor(this, R.color.dbIndex6); ObjectAnimator colorAnimator = ObjectAnimator.ofArgb(imgLogo, "colorFilter", colorGold, colorDb0, colorDb5, colorDb6); colorAnimator.setDuration(5000); colorAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); colorAnimator.start(); }
Give these changes a try—your logo should now transition between colors slowly and smoothly, no more flickering!
内容的提问来源于stack exchange,提问作者Badr Bujbara

