May 7, 2011

Android Tutorial . Animation - Frame By Frame, Layout



Android supports three types of animation:
  1. Frame-by-frame animation
    A series of frames is drawn one after the other at regular intervals.
  2. Layout animation
    Animate views inside a container view such as lists and tables.
  3. View animation
    Animate any general-purpose view.
The types #2 and #3 are a type of tweening animation which involves the drawing in between the key drawings. The idea is that knowing the beginning state and ending state of a drawing allows us to vary certain aspect of the drawing in time. This varying aspect could be color, position, size, etc.


 Frame By Frame Animation

I used the following Duke files to make the each frame of animation.
d1.gif: d2.gif: d3.gif: d4.gif: d5.gif:
d6.gif: d7.gif: d8.gif: d9.gif: d10.gif:


Let's look at the basic XML layout file,/res/layout/frame_animation_layout.xml.

Full List of Tutorial
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=
 "http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">
   <TextView android:id="@+id/textViewId1"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text=
 "Frame By Frame Animation of 10 Dukes"/>
   <Button
      android:id="@+id/startFAButtonId"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="Start Duke Animation"
      />
   <ImageView
      android:id="@+id/animationImage"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>
</LinearLayout>
The first control is the text control which is a simple TextView. Then the next control is a button to start and stop the animation. The last view is the ImageView, where we will do the animation. So, now we have the layout.
In Android, we accomplish frame-by-frame animation through a class in the graphics package called AnimationDrawable. We can tell from its name that it is like any other drawable that can work as background for any view. For example the background bitmaps are represented as Drawables. The class AnimationDrawable, in addition to being a Drawable, can take a list of other Drawable resources like images and render them at specified intervals. This class is really a thin wrapper around the animation support provided by the basic Drawable class.
To make use of the AnimationDrawable class, let's start with a set of Drawable resources in the /res/drawable subdirectory. Keep in mind that we need to put all the images into the same drawable directory as well as the xml file below.

/res/drawable/frame_animation.xml.
<animation-list xmlns:android=
 "http://schemas.android.com/apk/res/android"
android:oneshot="false">
   <item android:drawable="@drawable/d1" android:duration="50" />
   <item android:drawable="@drawable/d2" android:duration="50" />
   <item android:drawable="@drawable/d3" android:duration="50" />
   <item android:drawable="@drawable/d4" android:duration="50" />
   <item android:drawable="@drawable/d5" android:duration="50" />
   <item android:drawable="@drawable/d6" android:duration="50" />
   <item android:drawable="@drawable/d7" android:duration="50" />
   <item android:drawable="@drawable/d8" android:duration="50" />
   <item android:drawable="@drawable/d9" android:duration="50" />
   <item android:drawable="@drawable/d10" android:duration="50" />
</animation-list>

Let's look at our java code, :
package com.bogotobogo.frameanimation;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class FrameAnimation extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.frame_animations_layout);
       this.setupButton();
    }

    private void setupButton() {
    Button b = (Button)this.findViewById(R.id.startFAButtonId);
    b.setOnClickListener(
       new Button.OnClickListener() {
          public void onClick(View v) {
          parentButtonClicked(v);
          }
       });
    }

    private void parentButtonClicked(View v) {
       animate();
    }

    private void animate() {
       ImageView imgView = (ImageView)findViewById(R.id.animationImage);                                        
       imgView.setVisibility(ImageView.VISIBLE);
       imgView.setBackgroundResource(R.drawable.frame_animation);

       AnimationDrawable frameAnimation =
       (AnimationDrawable) imgView.getBackground();

       if (frameAnimation.isRunning()) {
          frameAnimation.stop();
       }
       else {
          frameAnimation.stop();
          frameAnimation.start();
       }
    }
}
Each frame points to one of the duke images we have assembled through their resource IDs. The animation-list tag gets converted into an AnimationDrawable object representing the collection of images. We will then need to set the Drawable as a background resource for out ImageView.
ImageView imgView = (ImageView)findViewById(R.id.animationImage);                                        
       imgView.setBackgroundResource(R.drawable.frame_animation);
With this code, Android knows that the resource ID R.drawable.frame_animation is an XML resource and accordingly constructs a AnimationDrawable Java object for it before setting it as the background. Once this is set, we can access this AnimationDrawable object by doing a "get" on the view object:
AnimationDrawable frameAnimation =
       (AnimationDrawable) imgView.getBackground();
Once we have the AnimationDrawable, we can use start() and stop() methods of this object to start and stop the animation.

FrameByFrameAnimationA FrameByFrameAnimationB

Files used in this Frame-By-Frame animation example, FrameAnimation.zip



3 comments:

  1. Thank you very much for the frame by frame android tutorial. it helped me answer a lot of questions i had about programming the frame by frame.

    But i still have some unanswered questions. such as instead of using the .gif images i used .png images it still works but the background is also put to screen which bothered me and im not sure how to get rid of it. also if the background was not a single color such as a full black background and instead is a picture image do i do a different method?

    ReplyDelete
  2. how do you make that animation into a wallpaper

    ReplyDelete
  3. nice explanation

    ReplyDelete