暂停 AnimationDrawable 并从同一帧恢复
Pause AnimationDrawable and resume from the same frame
我正在尝试使用 AnimationDrawable 为一组图像制作动画。用户应该能够通过单击按钮 pause/resume 动画。我正在这样做,使用 setVisible(boolean visible, boolean restart)
。不完全确定我是否正确理解了文档,但每次按下暂停键时,动画都会从头开始。
有什么方法可以从同一帧恢复动画吗?
...If restart is false, the drawable will resume from the most recent frame
明确一点:
activityAnimation.setVisible(false, false);
应该停止动画。
activityAnimation.setVisible(true, false);
应该从同一帧恢复动画(不是)。
这是我的代码:
动画 start()
在 onWindowFocusChanged
中调用。
动画和按钮创建于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);
}
}
});...
}
这是XML
文件的内容
<?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>
我注意到其中的一些旧帖子,但没有找到答案。
How to reset AnimationDrawable(本期的另一面)
How do I pause frame animation using AnimationDrawable? [Closed]
因为我也需要屏幕上的计时器,所以我的答案就是创建一个可运行的每秒替换 ImageView
背景。
大致思路如下:
创建 runnable,ImageView
和几个助手:
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);
}
};
在OnCreate
中绑定暂停和播放按钮,触发定时器并设置第一个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);
}
}
});
}
要暂停和恢复 AnimationDrawable,只需对其进行自定义并仅使用一个变量进行处理。
class CustomAnimationDrawable1() : AnimationDrawable() {
private var finished = false
private var animationFinishListener: AnimationFinishListener? = null
private var isPause = false
private var currentFrame = 0
fun setFinishListener(animationFinishListener: AnimationFinishListener?) {
this.animationFinishListener = animationFinishListener
}
interface AnimationFinishListener {
fun onAnimationFinished()
}
override fun selectDrawable(index: Int): Boolean {
val ret = if (isPause) {
super.selectDrawable(currentFrame)
} else {
super.selectDrawable(index)
}
if (!isPause) {
currentFrame = index
if (index == numberOfFrames - 1) {
if (!finished && ret && !isOneShot) {
finished = true
if (animationFinishListener != null) animationFinishListener!!.onAnimationFinished()
}
}
}
return ret
}
fun pause() {
isPause = true
}
fun resume() {
isPause = false
}
}
我正在尝试使用 AnimationDrawable 为一组图像制作动画。用户应该能够通过单击按钮 pause/resume 动画。我正在这样做,使用 setVisible(boolean visible, boolean restart)
。不完全确定我是否正确理解了文档,但每次按下暂停键时,动画都会从头开始。
有什么方法可以从同一帧恢复动画吗?
...If restart is false, the drawable will resume from the most recent frame
明确一点:
activityAnimation.setVisible(false, false);
应该停止动画。
activityAnimation.setVisible(true, false);
应该从同一帧恢复动画(不是)。
这是我的代码:
动画 start()
在 onWindowFocusChanged
中调用。
动画和按钮创建于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);
}
}
});...
}
这是XML
文件的内容
<?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>
我注意到其中的一些旧帖子,但没有找到答案。
How to reset AnimationDrawable(本期的另一面)
How do I pause frame animation using AnimationDrawable? [Closed]
因为我也需要屏幕上的计时器,所以我的答案就是创建一个可运行的每秒替换 ImageView
背景。
大致思路如下:
创建 runnable,
ImageView
和几个助手: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); } };
在
OnCreate
中绑定暂停和播放按钮,触发定时器并设置第一个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); } } }); }
要暂停和恢复 AnimationDrawable,只需对其进行自定义并仅使用一个变量进行处理。
class CustomAnimationDrawable1() : AnimationDrawable() {
private var finished = false
private var animationFinishListener: AnimationFinishListener? = null
private var isPause = false
private var currentFrame = 0
fun setFinishListener(animationFinishListener: AnimationFinishListener?) {
this.animationFinishListener = animationFinishListener
}
interface AnimationFinishListener {
fun onAnimationFinished()
}
override fun selectDrawable(index: Int): Boolean {
val ret = if (isPause) {
super.selectDrawable(currentFrame)
} else {
super.selectDrawable(index)
}
if (!isPause) {
currentFrame = index
if (index == numberOfFrames - 1) {
if (!finished && ret && !isOneShot) {
finished = true
if (animationFinishListener != null) animationFinishListener!!.onAnimationFinished()
}
}
}
return ret
}
fun pause() {
isPause = true
}
fun resume() {
isPause = false
}
}