在循环中更改图像 - Android

时间:2013-02-06 16:11:35

标签: java android for-loop thread-sleep

我想知道为什么我仍然无法想办法做到这一点。虽然看起来很简单,但我花了整整一天的时间。但是不能这样做。

我有一组骰子图像。 1.png,2.png,....和6.png。 我的布局中有一个ImageView。也就是说,

ImageView dice = (ImageView) findViewById(R.id.imageViewrollingdiceOne);

在这里,我想快速更改此imageView以查看使用上述6张图像的某种视觉/动画。为此,我写下了一段代码。

代码1:

for (int j=0;j<10;j++){
        int randomNum = random.nextInt(6);
            System.out.println("Random Value " + randomNum);
            dice.setImageResource(images[randomNum]);               
    }

输出:

没有视觉效果。 imageView保持不变,并在循环最后一次迭代时突然改变。 我认为这是因为循环执行速度非常快。 然后我做了以下事情。

代码2:

for (int j=0;j<10;j++){
        int randomNum = random.nextInt(6);
            System.out.println("Random Value " + randomNum);
            dice.setImageResource(images[randomNum]);
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }               
    }

输出:

同样没有视觉效果。 imageView保持不变,并在循环最后一次迭代时突然改变。 然后我做了以下事情。

代码3:

final Handler localHandler = new Handler();
    Runnable runnableObject = new Runnable() {
        public void run() {
            final ImageView dice = (ImageView) findViewById(R.id.imageViewrollingdiceOne);
            int randomNum = random.nextInt(6);
            System.out.println("Random Value" + randomNum);
            dice.setImageResource(images[randomNum]);
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    };
    for (int j=0;j<10;j++){
        localHandler.postDelayed(runnableObject, 1000);
    }

同样没有视觉效果。 imageView保持不变,并在循环最后一次迭代时突然改变。在所有三种情况下,logcat都没有任何错误。

我发现线程也不能解决问题。

3 个答案:

答案 0 :(得分:7)

首先,Android中已经有一个动画集可以帮助你在被称为 FrameAnimation 之后获得你的成就,这里有一个如何使用它的例子:< / p>

FrameAnimation Example

你的第一,第二和第三个代码在主线程中运行,你不应该在主线程中使用sleep!。

如果您仍想手动设置图像资源,可以使用以下代码:

    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {
            int randomNum = random.nextInt(6);
            dice.setImageResource(images[randomNum]);
            handler.postDelayed(this, 500);
        }
    }, 500);

答案 1 :(得分:4)

当您使用项目列表并逐个更改时间间隔时,这非常有用。最初i值应为0,列表大小取决于。

final Handler handler = new Handler();
handler.postDelayed(new Runnable(){
    public void run(){
        if(i<4) {
            galleryImg.setImageResource(myImageList[i]);
            i++;
        } else {
            i=0;
        }
        handler.postDelayed(this, 10000);
    }
}, 500);

答案 2 :(得分:1)

您可能没有看到更改的原因是因为对主UI线程的最终回调发生在您的线程完成执行后,您只看到最终结果。现在,这是我(可能很差)的理解,更精通它的人可能会纠正我。

那说你可能应该考虑使用AnimationDrawable对象:

ImageView sImage = (ImageView)findViewById(R.id.imageViewrollingdiceOne);
AnimationDrawable anim = new AnimationDrawable();

for (int j=0;j<6;j++) {
  anim.addFrame(new BitmapDrawable(images[j], 200);
}

sImage.setBackgroundDrawable(anim);
anim.setOneShot(false);
anim.start();

这假设您已经以随机顺序生成了images[]图像。如果你想在for-loop中更改你需要的任何代码。

它的作用是创建一个动画对象,就像你看到gif在更改之间设置延迟间隔(在此代码中为200毫秒)一样。如果您愿意,可以选择更改该号码。 setOneShot调用确保它循环而不是完成动画并停在最后一个图像上。