Drabuna
Drabuna

Reputation: 1225

Android TextSwitcher number sequence animation

I want to do following - animate number sequence change, and I'm using TextSwitcher. I've got users score and it changes from time to time. Is there a way to animate this change, to slowly increment this number from its current value to its result value? Something like http://josheinstein.com/blog/index.php/2010/02/silverlight-animated-turbotax-number-display/ but for Android.

Upvotes: 0

Views: 3715

Answers (3)

BrentM
BrentM

Reputation: 5757

I have created a class to animate numerical change by using the Android Interpolator of your choice. This allows you to control the rate of change using the same algorithms that are used for other animations in Android. For example you may prefer rather than the numerical change animating at a constant rate that the number changes fast to begin and then slows as it nears its final value.

You can read the full article about implementing this here.

Full source for the class to achieve this is available as a Gist here.

The animation of the text value is achieved using a ValueAnimator class with the Interpolator of your choice. Here is the main code which creates the animator and adds the listener to update the text on your View as the animation is executed.

public void execute(){ 
    mValueAnimator = ValueAnimator.ofFloat(mStartValue, mEndValue); 
    mValueAnimator.setDuration(mDuration); 
    mValueAnimator.setInterpolator(mInterpolator); 
    mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
    @Override 
        public void onAnimationUpdate(ValueAnimator valueAnimator) { 
            float current = Float.valueOf(valueAnimator.getAnimatedValue().toString()); 
            mView.setText(String.format("%." + mPrecision + "f", current)); 
        } 
     });    

    mValueAnimator.start(); 
} 

Upvotes: 1

gbero
gbero

Reputation: 3890

I know this is quite an old answer but here are my 2 cents. Be careful, some checks/code should be put in place if oldValue < value...

String values[] = new String[Math.abs(oldValue - value)];
int count = 0;
for (int i = oldValue; i < value; i++) {
    values[count++] = "" + i;
}

Animator animatorText = ObjectAnimator.ofObject(new AnimatedTextView(navigationBarBalanceAmountTextView), "Text", new TypeEvaluator<String>() {
    @Override
    public String evaluate(float fraction, String startValue, String endValue) {
        return (fraction < 0.5) ? startValue : endValue;
    }
},  values);    
animatorText.start();

Upvotes: 0

Raj
Raj

Reputation: 86

I was looking for the same, got a friend to help me, here is a working sample. Hope it works for you.

-Raj

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class TimerUpdateAnimatorActivity extends Activity {

    private static final int toValue = 20;
    private static final int fromValue = 0;
    private static final int FRAME_TIME_MS = 100;
    private static final String KEY = "i";
    private TextView animatedText;
    boolean isRunning = false;

    // background updating
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            try {
                int i= msg.getData().getInt(KEY);
                animatedText.setText(""+i);

            } catch (Exception err) {
            }
        }

    };

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        animatedText = (TextView) findViewById(R.id.animatedText);
    }

    public void onStart() {
        super.onStart();
        Thread background = new Thread(new Runnable() {
            public void run() {
                try {
                    for (int i = fromValue; i <= toValue && isRunning; i++) {
                        Thread.sleep(FRAME_TIME_MS);
                        Bundle data= new Bundle();
                        data.putInt(KEY, i);
                        Message message = handler.obtainMessage();
                        message.setData(data);
                        handler.sendMessage(message);
                    }
                }
                catch (Throwable t) {
                }
            }
        });
        isRunning = true;
        background.start();
    }

    public void onStop() {
        super.onStop();
        isRunning = false;
    }

}

Upvotes: 7

Related Questions