Animation

Drawable Animation

This is a useful technique for having a sequence of images displayed as a frame-by-frame animation. I found four images of a rocket, and dropped them into res/drawable-mdpi folder. (You can download my sample images below.)

Then I created rocket.xml, also in drawable-mdpi, with this animation specification:

<?xml version="1.0" encoding="utf-8"?>

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
                android:oneshot="false">
    <item android:drawable="@drawable/rocket0" android:duration="200" />
    <item android:drawable="@drawable/rocket1" android:duration="200" />
    <item android:drawable="@drawable/rocket2" android:duration="200" />
    <item android:drawable="@drawable/rocket3" android:duration="200" />
</animation-list>

Setting oneshot to false means that the animation will loop. The durations are in milliseconds.

Below are the individual images

Below are the individual images

To make this animation work, you just need to place an ImageView on the layout, and then load it like this:

    ImageView imageView = (ImageView) findViewById(R.id.imageView);
    imageView.setBackgroundResource(R.drawable.rocket);
    AnimationDrawable rocketAnim = (AnimationDrawable) imageView.getBackground();
    rocketAnim.start();

Property Animation

This is a very sophisticated form of animation that allows any value or property to change over time in a specified way. For example, let’s suppose we want to animate an integer value, between 0 and 360 – probably because it represents an angle.

        va = new ValueAnimator();
        va.setEvaluator(new IntEvaluator());
        va.setInterpolator(new AccelerateDecelerateInterpolator());
        va.setDuration(2000);
        va.addUpdateListener(this);
        va.setIntValues(0, 180);  // beginning and end of range
        va.start();

Other choices for the interpolater include LinearInterpolator and OvershootInterpolator. For the listener to work, the current Activity class must implement ValueAnimator.AnimatorUpdateListener. That means adding a method:

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Log.i("animate3", "At time " + animation.getCurrentPlayTime() +
                    " the value is " + animation.getAnimatedValue());
        imageView.setRotation((Integer)animation.getAnimatedValue());
        helloText.setText(animation.getAnimatedValue().toString());
    }

As you can see, the animation parameter can provide the current time, and the current animated value. The latter is an Integer object, but that can relatively easily be cast to a native int type, or converted toString where necessary.