I don't know whether this solution is best. But, it works!
In a nutshell, I created ValueAnimator
and set its repeat mode to INFINITE
. Then, I implemented Animator.AnimatorListener
to override onAnimationRepeat
, which is called when duration time ends. And then, inside onAnimationRepeat
I am generating next random color.
int nextColor; // class-scope variable
int startColor; // class-scope variable
final Random rnd = new Random();
final float[] hsv = new float[3];
final float[] from = new float[3];
final float[] to = new float[3];
//generate random initial color and next color
startColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
nextColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
// to get nicer smooth transition I'm using HSV
Color.colorToHSV(startColor, from);
Color.colorToHSV(nextColor, to);
final ValueAnimator anim = ValueAnimator.ofInt(startColor, nextColor);
// animate from the current color to the next color;
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
hsv[0] = from[0] + (to[0] - from[0]) * animation.getAnimatedFraction();
hsv[1] = from[1] + (to[1] - from[1]) * animation.getAnimatedFraction();
hsv[2] = from[2] + (to[2] - from[2]) * animation.getAnimatedFraction();
view.setBackgroundColor(Color.HSVToColor(hsv));
}
});
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
// generate next random color
startColor = Color.HSVToColor(to);
nextColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
Color.colorToHSV(startColor, from);
Color.colorToHSV(nextColor, to);
}
});
anim.setDuration(4000); // duration to change colors
anim.setRepeatCount(ValueAnimator.INFINITE);
anim.start();