Loading graphics/java/android/graphics/drawable/AnimationDrawable.java +47 −36 Original line number Diff line number Diff line Loading @@ -31,20 +31,23 @@ import android.os.SystemClock; import android.util.AttributeSet; /** * An object used to create frame-by-frame animations, defined by a series of Drawable objects, * which can be used as a View object's background. * An object used to create frame-by-frame animations, defined by a series of * Drawable objects, which can be used as a View object's background. * <p> * 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 * {@link #start()} to run the animation. * 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 {@link #start()} to run the * animation. * <p> * An AnimationDrawable defined in XML consists of a single <code><animation-list></code> element, * and a series of nested <code><item></code> tags. Each item defines a frame of the animation. * See the example below. * </p> * <p>spin_animation.xml file in res/drawable/ folder:</p> * <pre><!-- Animation frames are wheel0.png -- wheel5.png files inside the * res/drawable/ folder --> * An AnimationDrawable defined in XML consists of a single * {@code <animation-list>} element and a series of nested * {@code <item>} tags. Each item defines a frame of the animation. See * the example below. * <p> * spin_animation.xml file in res/drawable/ folder: * <pre> * <!-- Animation frames are wheel0.png through wheel5.png * files inside the res/drawable/ folder --> * <animation-list android:id="@+id/selected" android:oneshot="false"> * <item android:drawable="@drawable/wheel0" android:duration="50" /> * <item android:drawable="@drawable/wheel1" android:duration="50" /> Loading @@ -53,8 +56,8 @@ import android.util.AttributeSet; * <item android:drawable="@drawable/wheel4" android:duration="50" /> * <item android:drawable="@drawable/wheel5" android:duration="50" /> * </animation-list></pre> * * <p>Here is the code to load and play this animation.</p> * <p> * Here is the code to load and play this animation. * <pre> * // Load the ImageView that will host the animation and * // set its background to our AnimationDrawable XML resource. Loading Loading @@ -128,13 +131,17 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>Starts the animation, looping if necessary. This method has no effect * if the animation is running. Do not call this in the {@link android.app.Activity#onCreate} * method of your activity, because the {@link android.graphics.drawable.AnimationDrawable} is * not yet fully attached to the window. If you want to play * the animation immediately, without requiring interaction, then you might want to call it * from the {@link android.app.Activity#onWindowFocusChanged} method in your activity, * which will get called when Android brings your window into focus.</p> * Starts the animation, looping if necessary. This method has no effect * if the animation is running. * <p> * <strong>Note:</strong> Do not call this in the * {@link android.app.Activity#onCreate} method of your activity, because * the {@link AnimationDrawable} is not yet fully attached to the window. * If you want to play the animation immediately without requiring * interaction, then you might want to call it from the * {@link android.app.Activity#onWindowFocusChanged} method in your * activity, which will get called when Android brings your window into * focus. * * @see #isRunning() * @see #stop() Loading @@ -149,8 +156,8 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>Stops the animation. This method has no effect if the animation is * not running.</p> * Stops the animation. This method has no effect if the animation is not * running. * * @see #isRunning() * @see #start() Loading @@ -165,7 +172,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>Indicates whether the animation is currently running or not.</p> * Indicates whether the animation is currently running or not. * * @return true if the animation is running, false otherwise */ Loading @@ -175,8 +182,8 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>This method exists for implementation purpose only and should not be * called directly. Invoke {@link #start()} instead.</p> * This method exists for implementation purpose only and should not be * called directly. Invoke {@link #start()} instead. * * @see #start() */ Loading Loading @@ -231,12 +238,12 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * Add a frame to the animation * Adds a frame to the animation * * @param frame The frame to add * @param duration How long in milliseconds the frame should appear */ public void addFrame(Drawable frame, int duration) { public void addFrame(@NonNull Drawable frame, int duration) { mAnimationState.addFrame(frame, duration); if (mCurFrame < 0) { setFrame(0, true, false); Loading @@ -244,13 +251,16 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } private void nextFrame(boolean unschedule) { int next = mCurFrame+1; final int N = mAnimationState.getChildCount(); if (next >= N) { next = 0; int nextFrame = mCurFrame + 1; final int numFrames = mAnimationState.getChildCount(); final boolean isLastFrame = mAnimationState.mOneShot && nextFrame >= (numFrames - 1); // Loop if necessary. One-shot animations should never hit this case. if (!mAnimationState.mOneShot && nextFrame >= numFrames) { nextFrame = 0; } setFrame(next, unschedule, !mAnimationState.mOneShot || next < (N - 1)); setFrame(nextFrame, unschedule, !isLastFrame); } private void setFrame(int frame, boolean unschedule, boolean animate) { Loading @@ -262,6 +272,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An selectDrawable(frame); if (unschedule || animate) { unscheduleSelf(this); mRunning = false; } if (animate) { // Unscheduling may have clobbered these values; restore them Loading Loading @@ -341,6 +352,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } @Override @NonNull public Drawable mutate() { if (!mMutated && super.mutate() == this) { mAnimationState.mutate(); Loading @@ -366,8 +378,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An private int[] mDurations; private boolean mOneShot = false; AnimationState(AnimationState orig, AnimationDrawable owner, Resources res) { AnimationState(AnimationState orig, AnimationDrawable owner, Resources res) { super(orig, owner, res); if (orig != null) { Loading Loading
graphics/java/android/graphics/drawable/AnimationDrawable.java +47 −36 Original line number Diff line number Diff line Loading @@ -31,20 +31,23 @@ import android.os.SystemClock; import android.util.AttributeSet; /** * An object used to create frame-by-frame animations, defined by a series of Drawable objects, * which can be used as a View object's background. * An object used to create frame-by-frame animations, defined by a series of * Drawable objects, which can be used as a View object's background. * <p> * 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 * {@link #start()} to run the animation. * 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 {@link #start()} to run the * animation. * <p> * An AnimationDrawable defined in XML consists of a single <code><animation-list></code> element, * and a series of nested <code><item></code> tags. Each item defines a frame of the animation. * See the example below. * </p> * <p>spin_animation.xml file in res/drawable/ folder:</p> * <pre><!-- Animation frames are wheel0.png -- wheel5.png files inside the * res/drawable/ folder --> * An AnimationDrawable defined in XML consists of a single * {@code <animation-list>} element and a series of nested * {@code <item>} tags. Each item defines a frame of the animation. See * the example below. * <p> * spin_animation.xml file in res/drawable/ folder: * <pre> * <!-- Animation frames are wheel0.png through wheel5.png * files inside the res/drawable/ folder --> * <animation-list android:id="@+id/selected" android:oneshot="false"> * <item android:drawable="@drawable/wheel0" android:duration="50" /> * <item android:drawable="@drawable/wheel1" android:duration="50" /> Loading @@ -53,8 +56,8 @@ import android.util.AttributeSet; * <item android:drawable="@drawable/wheel4" android:duration="50" /> * <item android:drawable="@drawable/wheel5" android:duration="50" /> * </animation-list></pre> * * <p>Here is the code to load and play this animation.</p> * <p> * Here is the code to load and play this animation. * <pre> * // Load the ImageView that will host the animation and * // set its background to our AnimationDrawable XML resource. Loading Loading @@ -128,13 +131,17 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>Starts the animation, looping if necessary. This method has no effect * if the animation is running. Do not call this in the {@link android.app.Activity#onCreate} * method of your activity, because the {@link android.graphics.drawable.AnimationDrawable} is * not yet fully attached to the window. If you want to play * the animation immediately, without requiring interaction, then you might want to call it * from the {@link android.app.Activity#onWindowFocusChanged} method in your activity, * which will get called when Android brings your window into focus.</p> * Starts the animation, looping if necessary. This method has no effect * if the animation is running. * <p> * <strong>Note:</strong> Do not call this in the * {@link android.app.Activity#onCreate} method of your activity, because * the {@link AnimationDrawable} is not yet fully attached to the window. * If you want to play the animation immediately without requiring * interaction, then you might want to call it from the * {@link android.app.Activity#onWindowFocusChanged} method in your * activity, which will get called when Android brings your window into * focus. * * @see #isRunning() * @see #stop() Loading @@ -149,8 +156,8 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>Stops the animation. This method has no effect if the animation is * not running.</p> * Stops the animation. This method has no effect if the animation is not * running. * * @see #isRunning() * @see #start() Loading @@ -165,7 +172,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>Indicates whether the animation is currently running or not.</p> * Indicates whether the animation is currently running or not. * * @return true if the animation is running, false otherwise */ Loading @@ -175,8 +182,8 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * <p>This method exists for implementation purpose only and should not be * called directly. Invoke {@link #start()} instead.</p> * This method exists for implementation purpose only and should not be * called directly. Invoke {@link #start()} instead. * * @see #start() */ Loading Loading @@ -231,12 +238,12 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } /** * Add a frame to the animation * Adds a frame to the animation * * @param frame The frame to add * @param duration How long in milliseconds the frame should appear */ public void addFrame(Drawable frame, int duration) { public void addFrame(@NonNull Drawable frame, int duration) { mAnimationState.addFrame(frame, duration); if (mCurFrame < 0) { setFrame(0, true, false); Loading @@ -244,13 +251,16 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } private void nextFrame(boolean unschedule) { int next = mCurFrame+1; final int N = mAnimationState.getChildCount(); if (next >= N) { next = 0; int nextFrame = mCurFrame + 1; final int numFrames = mAnimationState.getChildCount(); final boolean isLastFrame = mAnimationState.mOneShot && nextFrame >= (numFrames - 1); // Loop if necessary. One-shot animations should never hit this case. if (!mAnimationState.mOneShot && nextFrame >= numFrames) { nextFrame = 0; } setFrame(next, unschedule, !mAnimationState.mOneShot || next < (N - 1)); setFrame(nextFrame, unschedule, !isLastFrame); } private void setFrame(int frame, boolean unschedule, boolean animate) { Loading @@ -262,6 +272,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An selectDrawable(frame); if (unschedule || animate) { unscheduleSelf(this); mRunning = false; } if (animate) { // Unscheduling may have clobbered these values; restore them Loading Loading @@ -341,6 +352,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } @Override @NonNull public Drawable mutate() { if (!mMutated && super.mutate() == this) { mAnimationState.mutate(); Loading @@ -366,8 +378,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An private int[] mDurations; private boolean mOneShot = false; AnimationState(AnimationState orig, AnimationDrawable owner, Resources res) { AnimationState(AnimationState orig, AnimationDrawable owner, Resources res) { super(orig, owner, res); if (orig != null) { Loading