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.
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();
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.