Frame by frame animation of Android Frame Animation example details

  • 2020-12-10 00:50:28
  • OfStack

The frame - by - frame animation of Android animation is analyzed. To share for your reference, the details are as follows:

Before I begin with an example, I quote a paragraph from the official document:

Frame animation is the process of displaying a series of images in a specified sequence, similar to the mechanism used to show movies, which we call frame-by-frame animation. The Frame animation can be defined in an XML file or implemented in full coding.

If it is defined in an XML file, we can place it in the anim or drawable directory under /res (/res/[anim | drawable]/ filename.xml) and the file name can be referenced in the code as a resource ID; If implemented entirely by coding, we need to use the AnimationDrawable object.

If the animation is defined in an XML file, the syntax is as follows:


<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
  android:oneshot=["true" | "false"] >
  <item
    android:drawable="@[package:]drawable/drawable_resource_name"
    android:duration="integer" />
</animation-list>

It should be noted that:

< animation-list > The element is required and must be the root element, which can contain one or more elements < item > Elements; android:onshot This animation is performed only once if defined as true, and 1 straight loop if defined as false.
< item > The element represents a frame animation, android:drawable specifies the image resource corresponding to the frame animation, and android:druation represents the duration of the frame, integer, in milliseconds.

I will not explain the following examples of the document, because we will also demonstrate this process with our own examples next.

We created a new project named anim and named the four consecutive images f1.png, f2.png, f3.png, ES59en4.png in the drawable directory, and then created a new frame.xml file:


<?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/f1" android:duration="300" />
  <item android:drawable="@drawable/f2" android:duration="300" />
  <item android:drawable="@drawable/f3" android:duration="300" />
  <item android:drawable="@drawable/f4" android:duration="300" />
</animation-list>

The frame.xml file can be placed in drawable or anim. The official document is placed in drawable, which you can place according to your preference. Both directories will work.

Then introduce one layout file res/layout/frame xml:


<?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">
 <ImageView
  android:id="@+id/frame_image"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:layout_weight="1"/>
 <Button
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="stopFrame"
  android:onClick="stopFrame"/>
 <Button
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="runFrame"
  android:onClick="runFrame"/>
</LinearLayout>

We defined an ImageView as the carrier of the animation, and then defined two buttons, namely stop and start animation.

Next, we introduce how to load the animation definition file to achieve the effect of the animation. The first thing we would write is this:


package com.scott.anim;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class FrameActivity extends Activity {
  private ImageView image;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.frame);
    image = (ImageView) findViewById(R.id.frame_image);
    image.setBackgroundResource(R.anim.frame);
    AnimationDrawable anim = (AnimationDrawable) image.getBackground();
    anim.start();
  }
}

It looks like a perfect 10, just like the official document says, but when we run this program, it only stops at frame 1 and doesn't animate as we expected, you may be disappointed to say: "Why?" ", and then you put the corresponding code in a button click event, the animation executed smoothly, and then moved back to onCreate, still no effect, this time you will probably angrily shout 1: "What the fuck!" . But why? How to solve it?

This happens because when we call start's start method in onCreate, the window Window object has not been fully initialized and AnimationDrawable cannot be fully appended to the window Window object. What do we do? We need to put this code in the onWindowFocusChanged method, and when Activity is shown to the user, the onWindowFocusChanged method is called, and that's when we implement our animation. Of course, onWindowFocusChanged is called after onCreate, as shown in figure 1:

Then we need to rewrite the following code:


package com.scott.anim;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class FrameActivity extends Activity {
  private ImageView image;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.frame);
    image = (ImageView) findViewById(R.id.frame_image);
  }
  @Override
  public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    image.setBackgroundResource(R.anim.frame);
    AnimationDrawable anim = (AnimationDrawable) image.getBackground();
    anim.start();
  }
}

Run 1 and the animation will display properly.

If in some cases, we need to implement an animation in a pure code way, we can write:


AnimationDrawable anim = new AnimationDrawable();
for (int i = 1; i <= 4; i++) {
  int id = getResources().getIdentifier("f" + i, "drawable", getPackageName());
  Drawable drawable = getResources().getDrawable(id);
  anim.addFrame(drawable, 300);
}
anim.setOneShot(false);
image.setBackgroundDrawable(anim);
anim.start();

The complete ES115en. java code is as follows:


package com.scott.anim;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class FrameActivity extends Activity {
  private ImageView image;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.frame);
    image = (ImageView) findViewById(R.id.frame_image);
  }
  @Override
  public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    image.setBackgroundResource(R.anim.frame); // Set the animation resource file to ImageView The background of 
    AnimationDrawable anim = (AnimationDrawable) image.getBackground(); // To obtain ImageView background , This has been compiled to AnimationDrawable
    anim.start();  // Start the animation 
  }
  public void stopFrame(View view) {
    AnimationDrawable anim = (AnimationDrawable) image.getBackground();
    if (anim.isRunning()) { // If it's running , stop 
      anim.stop();
    }
  }
  public void runFrame(View view) {
    // Fully coded animation effect 
    AnimationDrawable anim = new AnimationDrawable();
    for (int i = 1; i <= 4; i++) {
      // Gets by resource name and directory R.java , the corresponding resource in ID
      int id = getResources().getIdentifier("f" + i, "drawable", getPackageName());
      // According to the resource ID Access to the Drawable object 
      Drawable drawable = getResources().getDrawable(id);
      // Add this frame to AnimationDrawable In the 
      anim.addFrame(drawable, 300);
    }
    anim.setOneShot(false); // Set to loop
    image.setBackgroundDrawable(anim); // Set the animation to ImageView background 
    anim.start();  // Start the animation 
  }
}

I hope this article has been helpful to you in Android programming.


Related articles: