user2718135
user2718135

Reputation:

How to create color changing animation? (Android)

I have a TextView and some text in it. I need to create an animation with 30 seconds duration, and it will slowly change the color of text from green to red. Any ideas?

Upvotes: 15

Views: 18745

Answers (4)

Eddie
Eddie

Reputation: 77

Maybe I can build on pollaris' answer. Instead of using

ObjectAnimator a = ObjectAnimator.ofInt(...)

You can instead use,

ObjectAnimator a = ObjectAnimator.ofArgb(...)

Upvotes: 0

pollaris
pollaris

Reputation: 1321

As metioned above, use

setEvaluator(new ArgbEvaluator());

to eliminate the blinking. The following will fade the textview "tv" from green to red every 30,000 ms without any nervous blinking:

public void animateIt(){
    ObjectAnimator a = ObjectAnimator.ofInt(tv, "textColor", Color.GREEN, Color.RED);
    a.setInterpolator(new LinearInterpolator());
    a.setDuration(30000);
    a.setRepeatCount(ValueAnimator.INFINITE);
    a.setRepeatMode(ValueAnimator.REVERSE);
    a.setEvaluator(new ArgbEvaluator());
    AnimatorSet t = new AnimatorSet();
    t.play(a);
    t.start();
}

Upvotes: 2

Vaibhav Gupta
Vaibhav Gupta

Reputation: 79

Delyan's solution works, but as he pointed out, the color transition is not smooth. The following code should give you a smooth color transition:

    public static void changeTextColor(final TextView textView, int startColor, int endColor,
                                   final long animDuration, final long animUnit){
    if (textView == null) return;

    final int startRed = Color.red(startColor);
    final int startBlue = Color.blue(startColor);
    final int startGreen = Color.green(startColor);

    final int endRed = Color.red(endColor);
    final int endBlue = Color.blue(endColor);
    final int endGreen = Color.green(endColor);

    new CountDownTimer(animDuration, animUnit){
        //animDuration is the time in ms over which to run the animation
        //animUnit is the time unit in ms, update color after each animUnit

        @Override
        public void onTick(long l) {
            int red = (int) (endRed + (l * (startRed - endRed) / animDuration));
            int blue = (int) (endBlue + (l * (startBlue - endBlue) / animDuration));
            int green = (int) (endGreen + (l * (startGreen - endGreen) / animDuration));

            Log.d("Changing color", "Changing color to RGB" + red + ", " + green + ", " + blue);
            textView.setTextColor(Color.rgb(red, green, blue));
        }

        @Override
        public void onFinish() {
            textView.setTextColor(Color.rgb(endRed, endGreen, endBlue));
        }
    }.start();
}

Upvotes: 3

Delyan
Delyan

Reputation: 8911

1) 30s is a really, really long time, hardly any users would wait to see the end of it.

2) See Animating with ObjectAnimator. Something like ObjectAnimator.ofInt(textView, "textColor", Color.GREEN, Color.RED) should do what you want. Note, however, that the transition will be linear and will go through a lot of intermediary colors. until it hits #FF0000. You can of course specify the points in the middle but in general linear color transitions (in RGB) are not pretty.

Upvotes: 26

Related Questions