Animate ProgressBar update in Android

user1033552 picture user1033552 · Nov 7, 2011 · Viewed 67.2k times · Source

I am using a ProgressBar in my application which I update in onProgressUpdate of an AsyncTask. So far so good.

What I want to do is to animate the progress update, so that it does not just "jump" to the value but smoothly moves to it.

I tried doing so running the following code:

this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            while (progressBar.getProgress() < progress) {
                progressBar.incrementProgressBy(1);
                progressBar.invalidate();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    });

The problem is that the progress bar does not update its state until it finished its final value (progress variable). All states in between are not displayed on the screen. Calling progressBar.invalidate() didn't help either.

Any ideas? Thanks!

Answer

Eli Konky picture Eli Konky · Aug 2, 2013

I used android Animation for this:

public class ProgressBarAnimation extends Animation{
    private ProgressBar progressBar;
    private float from;
    private float  to;

    public ProgressBarAnimation(ProgressBar progressBar, float from, float to) {
        super();
        this.progressBar = progressBar;
        this.from = from;
        this.to = to;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        float value = from + (to - from) * interpolatedTime;
        progressBar.setProgress((int) value);
    }

}

and call it like so:

ProgressBarAnimation anim = new ProgressBarAnimation(progress, from, to);
anim.setDuration(1000);
progress.startAnimation(anim);

Note: if from and to value are too low to produce smooth animation just multiply them by a 100 or so. If you do so, don't forget to multiply setMax(..) as well.