在ImageView中显示连续的图像序列

4
我有一个蜡烛和火焰分别作为图像视图。当用户点击火焰时,它的可绘制资源会被设置为透明,表示火焰已熄灭。
我还想展示烟雾,因为火焰被吹灭了。为此,我有一些黑色烟雾的21张图片,可以快速地显示,让用户看到烟雾。以下是我的代码,在火焰被点击时挂起(R.drawable.smoke_22是火焰透明图像,R.drawable.candle_1是黄色火焰图像,flag用于跟踪火焰当前是否已经熄灭。flag=false表示火焰仍在燃烧):
int[] smokeImages = { R.drawable.smoke_1, R.drawable.smoke_2,
        R.drawable.smoke_3, R.drawable.smoke_4, R.drawable.smoke_5,
        R.drawable.smoke_6, R.drawable.smoke_7, R.drawable.smoke_8,
        R.drawable.smoke_9, R.drawable.smoke_10, R.drawable.smoke_11,
        R.drawable.smoke_12, R.drawable.smoke_13, R.drawable.smoke_14,
        R.drawable.smoke_15, R.drawable.smoke_16, R.drawable.smoke_17,
        R.drawable.smoke_18, R.drawable.smoke_19, R.drawable.smoke_20,
        R.drawable.smoke_21 };


    this.flamImageView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (flag) {
                flamImageView.setImageDrawable(getResources().getDrawable(
                        R.drawable.smoke_22));
                flag = false;
                startTimer();
            } else {
                flamImageView.setImageDrawable(getResources().getDrawable(
                        R.drawable.candle_1));
                flag = true;
                smokemageView.setImageResource(R.drawable.smoke_22);
            }
        }
    });
}

private void startTimer() {
    for (int i = 0; i < 21; i++) {
        try {
            Thread.sleep(250);
            smokemageView.setImageResource(smokeImages[i]);
        } catch (InterruptedException localInterruptedException) {
        }
    }
    smokemageView.setImageResource(R.drawable.smoke_22);
}

火焰会在反复触摸后熄灭并重新点燃,但我没有看到适当的烟雾动画。

这不是答案,只是一个小提示。Android支持动态gif吗?也许这可以很容易地解决你的问题? - user2707175
setImageResource需要在UI线程上调用。使用runOnUiThread或在处理程序上发布。 - njzk2
3个回答

11

你可以将for语句包装在while循环中,并由布尔值触发:只需在希望绘制对象动画化时将布尔值设置为true即可。

private void startTimer() {

while (timing) {
    for (int i = 0; i < 21; i++) {
        try {
            Thread.sleep(250);
            smokemageView.setImageResource(smokeImages[i]);
        } catch (InterruptedException localInterruptedException) {
      }
    }
  }
  smokemageView.setImageResource(R.drawable.smoke_22);
}

否则,您可以创建一个AnimationDrawable对象:(可能是更简单、更不容易出错的方法)

AnimationDrawable anim = new AnimationDrawable();
        anim.addFrame(
                getResources().getDrawable(R.drawable.smoke_1),
                250);
        anim.addFrame(
                getResources().getDrawable(R.drawable.smoke_2),
                250);
        anim.addFrame(
                getResources().getDrawable(R.drawable.smoke_3),
                250);
        anim.addFrame(
                getResources().getDrawable(R.drawable.smoke_4),
                250);

        //......So on, so forth until you have a satisfying animation sequence


        //set ImageView to AnimatedDrawable
        smokemageView.setImageDrawable(anim);

        //if you want the animation to loop, set false
        anim.setOneShot(false);
        anim.start();

我希望这能帮到你,编程愉快!


AnimationDrawable非常出色,而且运行得非常好。只有一个小问题,我不知道在动画完成一轮执行后如何设置不同的透明drawable的方法。请指教。编辑:哦!我怎么会这么笨,我必须将透明图像设置为最后一帧。感谢您的回答。 - Piyush-Ask Any Difference
没错,请确保在循环绘制表格后,设置透明的可绘制对象。很高兴能帮到你,祝你好运! - MattMatt
不错!1+我要是早点发现这个就好了。 - PaperThick

2

Thread.sleep非常糟糕,真的很糟糕。

然而,我建议您使用TimerHandler

以下是使用TimerTask的简单示例:

Timer timer = new Timer();
timer.schedule(new ImageTask(), 0, 250);

class ImageTask extends TimerTask {
    public void run() {
        // Change image here.
    }
}
ImageTask类将每250毫秒执行一次。您可以在那里更改您的图片。
Handler的微型示例:
final Handler handler = new Handler();
final Runnable r = new Runnable() {
    public void run() {
        // Change image here.
        handler.postDelayed(this, 250);
    }
};
handler.post(r);

这个方法可以解决你的问题,但并不是最好的方式。GreyBeardedGeek有一个更好的替代方案来解决你的问题。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接