This article analyzes the frame-by-frame animation of Android animation. Share it for your reference, as follows:
Before starting the example explanation, first quote a passage from the official document:
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 movies. We call it frame-by-frame animation. Frame animations can be defined in XML files or can be fully encoded.
If it is defined in an XML file, we can place it in the anim or drawable directory under /res (/res/[anim | drawable]/), and the file name can be referenced in the code as the resource ID; if it is implemented entirely by encoding, we need to use the AnimationDrawable object.
If you define an animation in an XML file, the syntax is as follows:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:andro android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>
What should be noted is:
The <animation-list> element is required and must be the root element, which can contain one or more <item> elements; android:onshot If defined as true, this animation will only be executed once, and if false, it will be looped.
The <item> element represents a frame of animation, android:drawable specifies the image resource corresponding to this frame of animation, android:druation represents the duration of this frame, an integer, and is in milliseconds.
I will not explain the following examples of the document, because next we will also demonstrate this process in combination with our own examples.
We create a new project called anim, name the four consecutive pictures,,,, and put them in the drawable directory, and then create a new file:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:andro 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>
We can place the file in the drawable or anim directory, and the official document is placed in the drawable. You can place it according to your preferences. Both directories can run.
Then introduce the layout file res/layout/:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android: 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 define an ImageView as the carrier of the animation, and then define two buttons, namely stop and start the animation.
Next, let’s introduce how to achieve animation effects by loading animation definition files. We will first write this:
package ; import ; import ; import ; import ; import ; import ; public class FrameActivity extends Activity { private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(); image = (ImageView) findViewById(.frame_image); (); AnimationDrawable anim = (AnimationDrawable) (); (); } }
It seems perfect, just like the official document, but when we run this program, we will find that it only stays in the first frame and does not appear the animation we expect. Maybe you will say disappointedly: "Why?", and then you put the corresponding code in a button click event, and the animation will be executed smoothly. Then you move back to onCreate, but it still has no effect. At this time, you will probably shout in anger: "What the fuck!". But, what's the reason? 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. It is at this time that we realize our animation effect. Of course, onWindowFocusChanged is called after onCreate, as shown in the figure:
Then we need to rewrite the code:
package ; import ; import ; import ; import ; import ; import ; public class FrameActivity extends Activity { private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(); image = (ImageView) findViewById(.frame_image); } @Override public void onWindowFocusChanged(boolean hasFocus) { (hasFocus); (); AnimationDrawable anim = (AnimationDrawable) (); (); } }
Run it and the animation will be displayed normally.
If in some cases, we need to implement an animation in pure code, we can write it like this:
AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { int id = getResources().getIdentifier("f" + i, "drawable", getPackageName()); Drawable drawable = getResources().getDrawable(id); (drawable, 300); } (false); (anim); ();
The complete code is as follows:
package ; import ; import ; import ; import ; import ; import ; public class FrameActivity extends Activity { private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(); image = (ImageView) findViewById(.frame_image); } @Override public void onWindowFocusChanged(boolean hasFocus) { (hasFocus); (); //Set the animation resource file as the background of the ImageView AnimationDrawable anim = (AnimationDrawable) (); //Get the ImageView background, which has been compiled into AnimationDrawable at this time (); //Start animation } public void stopFrame(View view) { AnimationDrawable anim = (AnimationDrawable) (); if (()) { //If it is running, stop (); } } public void runFrame(View view) { //Anime effect achieved by fully encoding AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { //Get the corresponding resource ID based on the resource name and directory int id = getResources().getIdentifier("f" + i, "drawable", getPackageName()); //Get Drawable object based on resource ID Drawable drawable = getResources().getDrawable(id); //Add this frame to AnimationDrawable (drawable, 300); } (false); //Set to loop (anim); //Set the animation as ImageView background (); //Start animation } }
I hope this article will be helpful to everyone's Android programming design.