kimo
kimo

Reputation: 1904

How to update Android UI elements from loop while it still looping?

I need to update Android buttons from loop, to make each button highlighted one by one
enter image description here

I was trying use AsyncTask without success, the same with Handler.
below the Handler example [part from the code, just to give you example]:

for(i=1;i<10;i++){
final int value = i;
Runnable runnable = new Runnable() {
    @Override
    public void run() {
            try {
                Thread.sleep(0);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Button currentButton = (Button) findViewById(value);
                    currentButton.setPressed(true);

                }
            });
    }
};
new Thread(runnable).start();

Any Idea how to reach UI elements one by one?
Another example: in below example in standard loop:
- get button by id
- setPressed(true) to make the button highlight
- execute the wanted function
- setPressed(false), only when the previous step was done.
The problem: while the loop running the buttons doesn't updated, only when the loop finished, in this case the user will not understand what step executed:
the below code is the event of Starting all the loop:

View.OnClickListener OnClickDoSomething(final Button button)  {
return new View.OnClickListener() {
    public void onClick(View v) {
        button.setText("text now set.. ");
        UpdateStep updateStep;
        for(int i=1; i<stepsArray.size();i++)
      {
         final int value = i;
         Button currentButton = (Button) findViewById(i);
         currentButton.setHighlightColor(0x7f050003);
         currentButton.setPressed(true);

         for(int x=0;x<900000;x++); // will be replaced with the real function

         currentButton.setPressed(false);
      }
    }
};

Upvotes: 0

Views: 3551

Answers (3)

Mohammad Ersan
Mohammad Ersan

Reputation: 12444

why you are using Thread and Handler with each other!!! i think this code will be more accurate:

        for (int i = 1; i < 10; i++) {
            final int value = i;
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    Button currentButton = (Button) findViewById(value);
                    currentButton.setPressed(true);

                }
            };
            handler.postDelayed(runnable, 50);
        } 

Upvotes: 0

Cyril Mottier
Cyril Mottier

Reputation: 1624

Are you sure this code is not crashing. Getting a view with an ID between 1 and 10 looks bad to me ;). You should normally use integers from the R.id class.

Secondly you should definitely use Handlers instead of Thread. Look at the postDelayed method.

Upvotes: 0

Ted Hopp
Ted Hopp

Reputation: 234807

You are sleeping for zero time. Try increasing the sleep delay in the loop to something where you would notice the delay. You may also need to invalidate the display to get it to refresh (although I think buttons do that automatically when their pressed state changes).

An alternative would be to use Handler's postDelayed or postAtTime method to post updates at 10 points in the future, each progressively further off into the future, and eliminate the sleep entirely from your loop.

Are you forgetting to un-press the previous button?

EDIT: You are launching 10 threads all at once and they execute in an unspecified order. Launch a single thread and put the loop inside the thread's run method.

Upvotes: 1

Related Questions