I am trying to animate a set of images using AnimationDrawable. The user should have the ability to pause/resume the animation on a click of a button. I am doing so, using setVisible(boolean visible, boolean restart)
. Not completely sure if I understand the documentation correctly, but every time pause is pressed, the animation starts from the beginning.
Is there any way to resume the animation from the same frame?
From AnimationDrawable API:
...If restart is false, the drawable will resume from the most recent frame
Just to be clear:
activityAnimation.setVisible(false, false);
Should stop the animation.
activityAnimation.setVisible(true, false);
Should resume the animation from the same frame (it doesn't).
Here is my code:
The animation start()
is called in onWindowFocusChanged
.
The animation and the buttons are created in onCreate
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
ImageView activityImage = (ImageView) findViewById(R.id.activity_image);
activityImage.setBackgroundResource(R.drawable.anim);
activityAnimation = (AnimationDrawable) activityImage.getBackground();
....
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageButton b = (ImageButton) v;
if ((Integer)b.getTag() == R.drawable.pause) {
b.setImageResource(R.drawable.play);
b.setTag(R.drawable.play);
activityAnimation.setVisible(false, false);
} else {
b.setImageResource(R.drawable.pause);
b.setTag(R.drawable.pause);
activityAnimation.setVisible(true, false);
}
}
});...
}
This is the content of the 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/one" android:duration="1000" />
<item android:drawable="@drawable/two" android:duration="1000" />
<item android:drawable="@drawable/three" android:duration="1000" />
<item android:drawable="@drawable/four" android:duration="1000" />
</animation-list>
I have noticed several of these old posts, but non had the answer.
How to reset AnimationDrawable (The other side of this issue)
How do I pause frame animation using AnimationDrawable? [Closed]
Since I needed a timer on the screen as well, the answer in my case was simply to create a runnable replace the ImageView
background every second.
Here is the general idea:
Create the runnable, ImageView
and few helpers:
ImageView exImage = null;
long startTime = 0;
long pauseTime = 0;
long pauseStartTime = 0;
List<Integer> animList = new ArrayList<>();
int animIt = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime - pauseTime;
double dSecs = (double) (millis / 100);
int pace = 10;
if (dSecs % pace == 0.0 && !animList.isEmpty()) {
animIt = (animIt == animList.size() - 1) ? 0 : animIt + 1;
exImage.setBackgroundResource(animList.get(animIt));
}
timerHandler.postDelayed(this, 100);
}
};
In OnCreate
bind the pause and play buttons, fire the timer and set the first ImageView
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercise);
// Set the image view
exImage = (ImageView) findViewById(R.id.image_zero);
exImage.setBackgroundResource(R.drawable.fe_0);
// Start the timer
timerHandler.postDelayed(timerRunnable, 0);
// Bind the buttons
ImageButton pp = (ImageButton) findViewById(R.id.button_play_pause_toggle);
pp.setImageResource(R.drawable.pause);
pp.setTag(R.drawable.pause);
pp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageButton pp = (ImageButton) v;
//Pause
if ((Integer) pp.getTag() == R.drawable.pause) {
pauseStartTime = System.currentTimeMillis();
timerHandler.removeCallbacks(timerRunnable);
} else { // Resume
pauseTime += System.currentTimeMillis() - pauseStartTime;
timerHandler.postDelayed(timerRunnable, 0);
}
}
});
}