使用处理程序检测动画的结束
Detecting the end of an animation using a handler
在下面的代码中,我将 3 张图像存储在 imageArray
中。我正在使用处理程序为图像制作动画,但它不断循环,我希望它只对 运行 动画进行一次。
我想做的是看是否到第3张图,然后停止动画。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grade_four__place_value);
final ImageView image1 = (ImageView) findViewById(R.id.im1);
final int[] imageArray = {(R.drawable.pl1),
(R.drawable.pl2),
(R.drawable.pl3)};
final Button btn2 = (Button) findViewById(R.id.button2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int i = 0;
public void run() {
image1.setImageResource(imageArray[i]);
i++;
if (i > imageArray.length - 1) {
i = 0;
}
handler.postDelayed(this, 300); // for interval...
}
};
handler.postDelayed(runnable, 500); // for initial delay..
btn2.setVisibility(View.INVISIBLE);
}
});
尝试改变
i++;
if (i > imageArray.length - 1) {
i = 0;
}
handler.postDelayed(this, 300);
至
if (i < imageArray.length - 1) {
handler.postDelayed(this, 300);
}
i++;
您的 Runnable 代码在每次通过后都会延迟将自己发布到处理程序中。当您的 i
变量大于或等于数组大小时,只需设置 i=0;
- 来自 run()
方法的 return。它不会达到handler.postDelayed(this, 300)
,所以下一帧将不会显示。
样本:
final int[] imageArray = {R.drawable.ic, R.drawable.ic, R.drawable.ic};
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
private int i = 0;
@Override
public void run() {
i++;
if(i > imageArray.length - 1) {
Log.e("ASD", "Done");
return;
}
Log.e("ASD", "Preparing next iteration");
handler.postDelayed(this, 300);
}
};
handler.postDelayed(runnable, 500);
无论如何,提供帧动画并不是最好的方式。
您是否考虑过使用 Drawable Animation 而不是 Handler
?
您基本上会在 xml 中创建一个动画集,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/pl1" android:duration="300" />
<item android:drawable="@drawable/pl2" android:duration="300" />
<item android:drawable="@drawable/pl3" android:duration="300" />
</animation-list>
我们把这个文件命名为animation_drawable.xml
,放在drawable
文件夹中。之后,只需使用以下代码启动动画:
final AnimationDrawable drawable = (AnimationDrawable) getResources().getDrawable(R.drawable.animation_drawable);
image1.setImageDrawable(drawable);
drawable.start();
image1.postDelayed(new Runnable() {
@Override
public void run() {
image1.clearAnimation();
// Handle your animation ending here
}
}, drawable.getDuration());
就是这样!我知道这是一个 hack 解决方案,但我认为 Drawable 动画使代码更清晰、更紧凑,但听动画结束需要一些解决方法。
仅当未到达图像数组末尾时才安排 Runnable:
public void run() {
image1.setImageResource(imageArray[i]);
i++;
if (i < imageArray.length) {
handler.postDelayed(this, 300); // for interval...
}
}
在下面的代码中,我将 3 张图像存储在 imageArray
中。我正在使用处理程序为图像制作动画,但它不断循环,我希望它只对 运行 动画进行一次。
我想做的是看是否到第3张图,然后停止动画。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grade_four__place_value);
final ImageView image1 = (ImageView) findViewById(R.id.im1);
final int[] imageArray = {(R.drawable.pl1),
(R.drawable.pl2),
(R.drawable.pl3)};
final Button btn2 = (Button) findViewById(R.id.button2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int i = 0;
public void run() {
image1.setImageResource(imageArray[i]);
i++;
if (i > imageArray.length - 1) {
i = 0;
}
handler.postDelayed(this, 300); // for interval...
}
};
handler.postDelayed(runnable, 500); // for initial delay..
btn2.setVisibility(View.INVISIBLE);
}
});
尝试改变
i++;
if (i > imageArray.length - 1) {
i = 0;
}
handler.postDelayed(this, 300);
至
if (i < imageArray.length - 1) {
handler.postDelayed(this, 300);
}
i++;
您的 Runnable 代码在每次通过后都会延迟将自己发布到处理程序中。当您的 i
变量大于或等于数组大小时,只需设置 i=0;
- 来自 run()
方法的 return。它不会达到handler.postDelayed(this, 300)
,所以下一帧将不会显示。
样本:
final int[] imageArray = {R.drawable.ic, R.drawable.ic, R.drawable.ic};
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
private int i = 0;
@Override
public void run() {
i++;
if(i > imageArray.length - 1) {
Log.e("ASD", "Done");
return;
}
Log.e("ASD", "Preparing next iteration");
handler.postDelayed(this, 300);
}
};
handler.postDelayed(runnable, 500);
无论如何,提供帧动画并不是最好的方式。
您是否考虑过使用 Drawable Animation 而不是 Handler
?
您基本上会在 xml 中创建一个动画集,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/pl1" android:duration="300" />
<item android:drawable="@drawable/pl2" android:duration="300" />
<item android:drawable="@drawable/pl3" android:duration="300" />
</animation-list>
我们把这个文件命名为animation_drawable.xml
,放在drawable
文件夹中。之后,只需使用以下代码启动动画:
final AnimationDrawable drawable = (AnimationDrawable) getResources().getDrawable(R.drawable.animation_drawable);
image1.setImageDrawable(drawable);
drawable.start();
image1.postDelayed(new Runnable() {
@Override
public void run() {
image1.clearAnimation();
// Handle your animation ending here
}
}, drawable.getDuration());
就是这样!我知道这是一个 hack 解决方案,但我认为 Drawable 动画使代码更清晰、更紧凑,但听动画结束需要一些解决方法。
仅当未到达图像数组末尾时才安排 Runnable:
public void run() {
image1.setImageResource(imageArray[i]);
i++;
if (i < imageArray.length) {
handler.postDelayed(this, 300); // for interval...
}
}