I'm new to Android platform. I'm using the following to animate a set of 16 "frames" using AminationDrawable in my app:
In the XML file I have:
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/image_1" android:duration="200" />
<item android:drawable="@drawable/image_1_25" android:duration="200" />
<item android:drawable="@drawable/image_1_5" android:duration="200" />
<item android:drawable="@drawable/image_1_75" android:duration="200" />
<item android:drawable="@drawable/image_2" android:duration="200" />
<item android:drawable="@drawable/image_2_25" android:duration="200" />
<item android:drawable="@drawable/image_2_5" android:duration="200" />
<item android:drawable="@drawable/image_2_75" android:duration="200" />
<item android:drawable="@drawable/image_3" android:duration="200" />
<item android:drawable="@drawable/image_3_25" android:duration="200" />
<item android:drawable="@drawable/image_3_5" android:duration="200" />
<item android:drawable="@drawable/image_3_75" android:duration="200" />
<item android:drawable="@drawable/image_4" android:duration="200" />
<item android:drawable="@drawable/image_4_25" android:duration="200" />
<item android:drawable="@drawable/image_4_5" android:duration="200" />
<item android:drawable="@drawable/image_4_75" android:duration="200" />
</animation-list>
In the Java code I have the following
first I'm declaring the class and adding an onCreate()
method where I set up the animation.
public class MyNewActivity extends Activity
{
// member variables (accessible from within class methods below).
AnimationDrawable mainAnimation;
long mSpeed = 50;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.my_widget);
// set up image
ImageView mainImage = (ImageView) findViewById(R.id.image_widget);
mainImage.setBackgroundResource(R.drawable.animated_image);
mainAnimation = (AnimationDrawable) mainImage.getBackground();
};
<...snip...>
...then later on I start my drawing when the user presses a button I call the following to start the animation moving:
private void start()
{
// start the image rotating.
if (mainAnimation.isRunning())
mainAnimation.stop();
int numFrames = mainAnimation.getNumberOfFrames();
for (int ii = 0; ii < numFrames; ii++ )
{
// change the animation speed.
Drawable d = mainAnimation.getFrame(ii);
mainAnimation.scheduleDrawable(d, mainAnimation, mSpeed);
}
}
<...snip...>
So elsewhere in the code I have a place to adjust the member variable mSpeed
. If I do this and then call start()
, the animation will start, however the speed is always the same (essentially what was defined in the XML above. My question is, how can I modify the "duration" of the frames to move this animation faster/slower based on user input? I see no way to modify a "duration" state, and was under the assumption the ScheduleDrawable()
call above would change the drawing's frames duration.
You have to create a new folder called anim under res directory and make an xml file under anim folder. This method starts the animation. This method sets the duration of an animation.
In Android Frame Animation, you will be swapping frames repeatedly, so that it appears continuous to the human eye and we feel that it is animated. Frame is referred to an image. So to implement frame by frame animation in android, one needs to have set of images, which describes a motion.
Animation is the process of adding a motion effect to any view, image, or text. With the help of an animation, you can add motion or can change the shape of a specific view. Animation in Android is generally used to give your UI a rich look and feel.
I had the same problem but I managed to solve it when reading the source code of AnimationDrawable by implementing my own AnimationDrawable class that extends AnimationDrawable and override the Run()
method and add setDuration()
method which allows me to set the duration as follow:
By reviewing the original run method we see that it do the same but by calling scheduleSelf(this, SystemClock.uptimeMillis() + duration);
with the duration you specified when adding the frame so I changed it. I also add duration because I use the same for all my frames but you can use array of new duration.
import android.graphics.drawable.AnimationDrawable;
import android.os.SystemClock;
public class MyAnimationDrawable extends AnimationDrawable {
private volatile int duration;//its volatile because another thread will update its value
private int currentFrame;
public MyAnimationDrawable() {
currentFrame = 0;
}
@Override
public void run() {
int n = getNumberOfFrames();
currentFrame++;
if (currentFrame >= n) {
currentFrame = 0;
}
selectDrawable(currentFrame);
scheduleSelf(this, SystemClock.uptimeMillis() + duration);
}
public void setDuration(int duration) {
this.duration = duration;
//we have to do the following or the next frame will be displayed after the old duration
unscheduleSelf(this);
selectDrawable(currentFrame);
scheduleSelf(this, SystemClock.uptimeMillis()+duration);
}
}
It's my first answer so I hope it helps you and it's explained well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With