Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change start/end values of ValueAnimator on animation repeat?

I want to setup infinite color animation, that would change color from random start color to random end color, then from that random end color to next random end color and etc. I tried to setup this value animator:

ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), randomColorStart, randomColorEnd);

And then tried to update randomColorStart and randomColorEnd on onAnimationRepeat() method, but updated values do not affect animation. How could I accomplish this?

like image 646
wilkas Avatar asked Oct 24 '25 06:10

wilkas


1 Answers

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();
like image 101
SpiralDev Avatar answered Oct 25 '25 22:10

SpiralDev