Detailed explanation of Frame Animation of Android animation

Before starting the example explanation, let's quote a passage from the official documentation:

Frame animation is a process in which a series of pictures are displayed in a certain order, which is very similar to the mechanism of playing a movie. We call it frame-by-frame animation. Frame animations can be defined in XML files or fully encoded.

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

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

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

have to be aware of is:

The <animation-list> element is required and must be used as the root element, which can contain one or more <item> elements; Android :onshot If defined as true, the animation will only be executed once, and if it is false, it will keep looping .

The <item> element represents a frame of animation, android:drawable specifies the image resource corresponding to this frame of animation, and android:druation represents the duration of this frame, an integer, in milliseconds.

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

We create a new project named anim, name the four consecutive pictures as f1.png, f2.png, f3.png, f4.png, put them in the drawable directory, and then create a new frame.xml file:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:oneshot="false">  
  4.     <item android:drawable="@drawable/f1" android:duration="300" />  
  5.     <item android:drawable="@drawable/f2" android:duration="300" />  
  6.     <item android:drawable="@drawable/f3" android:duration="300" />  
  7.     <item android:drawable="@drawable/f4" android:duration="300" />  
  8. </animation-list>  
We can place the frame.xml file in the drawable or anim directory. The official document is placed in the drawable. You can place it according to your preferences. Both directories can be run.

Then introduce the layout file res/layout/frame.xml:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.   xmlns:android="http://schemas.android.com/apk/res/android"  
  4.   android:orientation="vertical"  
  5.   android:layout_width="fill_parent"  
  6.   android:layout_height="fill_parent">  
  7.   <ImageView  
  8.     android:id="@+id/frame_image"  
  9.     android:layout_width="fill_parent"  
  10.     android:layout_height="fill_parent"  
  11.     android:layout_weight="1"/>  
  12.   <Button  
  13.     android:layout_width="fill_parent"  
  14.     android:layout_height="wrap_content"  
  15.     android:text="stopFrame"  
  16.     android:onClick="stopFrame"/>  
  17.   <Button  
  18.     android:layout_width="fill_parent"  
  19.     android:layout_height="wrap_content"  
  20.     android:text="runFrame"  
  21.     android:onClick="runFrame"/>  
  22. </LinearLayout>  
We define an ImageView as the carrier of the animation, and then define two buttons to stop and start the animation.

Next, we will introduce how to achieve the effect of animation by loading the animation definition file. We would first write this:

  1. package com.scott.anim;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.drawable.AnimationDrawable;  
  5. import android.graphics.drawable.Drawable;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.widget.ImageView;  
  9.   
  10. public class FrameActivity extends Activity {  
  11.       
  12.     private ImageView image;  
  13.       
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super .onCreate (savedInstanceState);  
  17.         setContentView(R.layout.frame);  
  18.         image = (ImageView) findViewById(R.id.frame_image);  
  19.           
  20.         image.setBackgroundResource(R.anim.frame);  
  21.         AnimationDrawable anim = (AnimationDrawable) image.getBackground();  
  22.         anim.start();  
  23.     }  
  24. }  
It seems to be perfect, as written in the official documentation, but when we run this program, we will find that it only stays in the first frame, and the animation we expect does not appear. Maybe you will be disappointed and say: "Why? ”, and then you put the corresponding code in the click event of a button, the animation will be executed smoothly, and then move back to onCreate, but it still has no effect. At this time, it is estimated that you will shout angrily: “What the fuck!” . But why? How to solve it?

This phenomenon occurs because when we call the start method of AnimationDrawable in onCreate, the window Window object has not been fully initialized, and the AnimationDrawable cannot be completely appended to the window Window object, so what should we do? We need to put this code in the onWindowFocusChanged method. When the Activity is displayed to the user, the onWindowFocusChanged method will be called, and it is at this time that we implement our animation effect. Of course, onWindowFocusChanged is called after onCreate, as shown in the figure:


Then we need to rewrite the code:

  1. package com.scott.anim;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.drawable.AnimationDrawable;  
  5. import android.graphics.drawable.Drawable;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.widget.ImageView;  
  9.   
  10. public class FrameActivity extends Activity {  
  11.       
  12.     private ImageView image;  
  13.       
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super .onCreate (savedInstanceState);  
  17.         setContentView(R.layout.frame);  
  18.         image = (ImageView) findViewById(R.id.frame_image);  
  19.     }  
  20.       
  21.     @Override  
  22.     public void onWindowFocusChanged(boolean hasFocus) {  
  23.         super.onWindowFocusChanged(hasFocus);  
  24.         image.setBackgroundResource(R.anim.frame);  
  25.         AnimationDrawable anim = (AnimationDrawable) image.getBackground();  
  26.         anim.start();  
  27.     }  
  28. }  
Run it, the animation can be displayed normally.

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

  1. AnimationDrawable anim = new AnimationDrawable();  
  2. for (int i = 1; i <= 4; i++) {  
  3.     int id = getResources().getIdentifier("f" + i, "drawable", getPackageName());  
  4.     Drawable drawable = getResources().getDrawable(id);  
  5.     anim.addFrame(drawable, 300);  
  6. }  
  7. anim.setOneShot(false);  
  8. image.setBackgroundDrawable(anim);  
  9. anim.start();  
The complete FrameActivity.java code is as follows:
  1. package com.scott.anim;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.drawable.AnimationDrawable;  
  5. import android.graphics.drawable.Drawable;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.widget.ImageView;  
  9.   
  10. public class FrameActivity extends Activity {  
  11.       
  12.     private ImageView image;  
  13.       
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super .onCreate (savedInstanceState);  
  17.         setContentView(R.layout.frame);  
  18.         image = (ImageView) findViewById(R.id.frame_image);  
  19.     }  
  20.       
  21.     @Override  
  22.     public void onWindowFocusChanged(boolean hasFocus) {  
  23.         super.onWindowFocusChanged(hasFocus);  
  24.         image.setBackgroundResource(R.anim.frame);   //Set the animation resource file as the background of ImageView  
  25.         AnimationDrawable anim = (AnimationDrawable) image.getBackground();  //Get the ImageView background, which has been compiled into AnimationDrawable  
  26.         anim.start();    //Start animation  
  27.     }  
  28.       
  29.     public void stopFrame(View view) {  
  30.         AnimationDrawable anim = (AnimationDrawable) image.getBackground();  
  31.         if  (anim.isRunning()) {  //If running, stop  
  32.             anim.stop();  
  33.         }  
  34.     }  
  35.       
  36.     public void runFrame(View view) {  
  37.         // fully coded animation effect  
  38.         AnimationDrawable anim = new AnimationDrawable();  
  39.         for (int i = 1; i <= 4; i++) {  
  40.             //Get the corresponding resource ID in R.java according to the resource name and directory  
  41.             int id = getResources().getIdentifier("f" + i, "drawable", getPackageName());  
  42.             //Get the Drawable object according to the resource ID  
  43.             Drawable drawable = getResources().getDrawable(id);  
  44.             //Add this frame to AnimationDrawable  
  45.             anim.addFrame(drawable, 300);  
  46.         }  
  47.         anim.setOneShot( false );  //set to loop  
  48.         image.setBackgroundDrawable(anim);   //Set the animation to the ImageView background  
  49.         anim.start();    //Start animation  
  50.     }  
  51. }  

Okay, here first, thank you all.



Original URL: http://blog.csdn.net/liuhe688/article/details/6657776

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324220178&siteId=291194637