Wednesday, July 11, 2012

frame-by-frame animation on Android using AnimationDrawable




While developing Redcard (which got started by a joke among friends while watching Euro 2012) I wanted to have a small animation alternating between two images mimicking a referee hand gesture, telling the player to shut-up (there is sound effect too. It uses text-to-speech, but that is for another post).

In Android API reference I saw the class AnimationDrawable, which looks like a perfect solution.  The class is described like this:

The simplest way to create a frame-by-frame animation is to define the animation in an XML file, placed in the res/drawable/ folder, and set it as the background to a View object. Then, call start () to run the animation.
An AnimationDrawable defined in XML consists of a single <animation-list> element, and a series of nested <item> tags. Each item defines a frame of the animation.

It sounds simple enough but it took me while to get it to work.  Here's what I needed to do to get it working.

First I defined my animation in /res/anim/my_anim.xml


<?xml version="1.0" encoding="utf-8"?>
<animation-list 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:oneshot="false"
  android:visible="true">
  <item android:drawable="@drawable/frame_1" android:duration="500"/>
  <item android:drawable="@drawable/frame_2" android:duration="500"/>
</animation-list>


framd_1 and frame_2 are png images stored in drawable directories.  There are different sizes to support different screen resolutions.

Then, in an activity layout, I defined an ImageView like this

<ImageView
 android:id="@+id/imgMyAnim"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerHorizontal="true"
 android:layout_centerVertical="true"
 android:background="@anim/my_anim" />

Notice the background, which points to my animation XML.

In my activity source code, I obviously needed to define the ImageView.  I also defined mMyAnim, which is of type AnimationDrawable.

private ImageView mImgMyAnim;
private AnimationDrawable mMyAnim; 
mImgMyAnim will be referencing the ImageView previously defined in the layout.  It got done in onCreate()

mImgMyAnim = (ImageView) vgFinger.findViewById(R.id.imgMyAnim);
mImgMyAnim.setBackgroundResource(R.anim.my_anim);
mMyAnim = (AnimationDrawable) mImgFinger.getBackground();
Notice that mMyAnim is assigned the background of the ImageView (to which the actual animation is pointed).

The setup is completed.  To start the animation, simply call start()
mMyAnim.start();
The stop() function stops the animation.

No comments:

Post a Comment