Change Images in Loop - Android

I am wondering why until now I could not find a way to do this. Although it sounds very simple, I've spent my entire day doing it. But I couldn't do it.

I have a lot of dice images. 1.png, 2.png, .... and 6.png. I have an ImageView in my layout. I.e,

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

      

Here I want to quickly change this imageView to see some kind of visual / animation using above 6 images. For this I wrote the following piece of code.

Code 1:

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

      

Output:

There is no visual. The imageView remains unchanged and changes suddenly on the last iteration of the loop. I thought it was because the loop is very fast. Then I did the following.

Code 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();
            }               
    }

      

Output:

Again, no visual. The imageView remains unchanged and changes suddenly on the last iteration of the loop. Then I did the following.

Code 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);
    }

      

Again, no visual. The imageView remains unchanged and changes suddenly on the last iteration of the loop. There are no logcat errors in all three cases.

I found that multithreading doesn't help either.

+3


source to share


3 answers


First of all, android already has a set of animations that can help you achieve what you are after FrameAnimation , here is an example of how to use it:

FrameAnimation example

Your first, second and third codes run on the main thread, you should never sleep on the main thread!



If you want to manually set the image resource anyway, you can use this code:

    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);

      

+7


source


This is useful when you are using a list of items and change them at a time interval each time. Initially, the value i

should be 0, the size of the list depends.



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);

      

+4


source


The reason you probably don't see the change is because the final callback to the main UI thread happens after the thread finishes executing and you only see the final result. Now this is my (possibly poor) understanding and someone more knowledgeable about it can probably correct me.

To say , you should probably be looking for an object 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();

      

It is assumed that you have created images[]

with images in random order. If you want to change this, put whatever code you need in the for-loop.

What it does is create an animation object similar to how you would see it working gif

with a given delay interval between changes (in this code its 200ms). You can change this number if you like. When called, setOneShot

it ends the loop rather than ending the animation and stops at the last image.

+1


source







All Articles