Bazouk55555
Bazouk55555

Reputation: 567

Java Android studio: change an attribute of a View inside its own listener

I have a question about the Android Studio:

I have an Image view. Let's call it ImageView. I call the method setOnCLickListener on this ImageView with a listener new View.OnclickListener(). In the method onClick() of this listener, I change an attribute (the color, the image itself...) of this imageView. For example, I change the image with imageView.setImageResource(R.drawable.new_image). I then wait for 10 sec with Thread.sleep(10000). I then set back the previous image with imageView.setImageResource(R.drawable.previous_image).

Here is my question:

I expect the ImageView to change its image for 10 sec and then have the previous image back. However, I see no change on this ImageView. I only see the first image...Could someone explain me why?

I hope I was clear enough...Thank you in advance for your help :) !!

Upvotes: 1

Views: 653

Answers (2)

Gergely Kőrössy
Gergely Kőrössy

Reputation: 6393

First of all, you should read the Processes and Threads guide to understand how threading works on Android.

If you're done with with that, you'll understand that what you do is really bad because you freeze the main (UI) thread which means the application will not respond to any events until the 10 seconds pass. This also results in an ANR (Application Not Responding) dialog which is pretty bad UX.

You basically need to delegate the waiting period to another thread (or a queue at least), then when the time comes, go back to the UI thread and set whatever view attribute you want. There are many ways to achieve this, you should read Communicating with the UI Thread for more details. Here's just a quick sample:

Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // write here what you want to happen in 10 seconds on the UI thread
    }
}, 10000); // 10s = 10,000ms

Here are some notes though:

  1. Save the Runnable you create here to a variable because if the user navigates away from this screen within the 10 seconds, it will still run the code inside, which might result in various exceptions. In this case you need to remove that Runnable from the handler by calling handler.removeCallbacks(runnable); when the user leaves the screen.
  2. Don't create a new Handler instance every time the click event happens. Create it in the Activity's onCreate(...) method and use that instance in the rest of the screen.
  3. You could create the Handler without the Looper parameter, which would create the handler for the current thread's Looper and that would be fine now since it's being created on the UI thread. However, I decided it's better to show you the safer way since you might end up doing something similar on a background thread that could result in unexpected behavior if you don't understand the threading yet.

Upvotes: 2

Ramanlfc
Ramanlfc

Reputation: 8354

R.id.drawable.previous_image ?. It should be R.drawable.previous_image

Upvotes: 3

Related Questions