使用处理程序检测动画的结束

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...
    }
}