2011-09-06 174 views
0

我需要從循環更新的Android按鈕,使每個按鈕高亮逐一
enter image description here如何在循環中更新循環中的Android UI元素?

我試圖使用的AsyncTask沒有成功,同樣與處理程序。
處理程序下面的例子[從代碼的一部分,只給你舉例]:

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

任何想法如何到達用戶界面元素逐一?
又如:例如在標準循環如下:
- 通過ID獲得按鈕
- setPressed(真),使按鈕高亮
- 執行想要的功能
- setPressed(假的),只有當先前的一步完成。
問題:在運行按鈕的循環沒有更新,只有當循環結束後,在此情況下,用戶不會明白什麼步驟執行:
下面的代碼是開始,所有環路的事件:

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); 
     } 
    } 
}; 
+0

您應該首先了解*爲什麼*您的應用程序在循環中時UI不會更新。接下來,您應該(如您第一次嘗試的那樣)學習如何異步運行代碼,即在單獨的線程上運行代碼。 –

+1

@Ed - 這不是在UI線程上運行。注意發佈代碼的最後一行? –

+0

@Ted:....... d'噢。好吧,它運行得太快了。 –

回答

1

你正在零時間睡覺。嘗試將循環中的睡眠延遲增加到您會注意到延遲的地方。您可能還需要使顯示無效以使其刷新(儘管我認爲按鈕會在按下狀態更改時自動執行此操作)。

另一種方法是使用Handler的postDelayedpostAtTime方法在未來發布10個更新點的更新,每個更新會逐漸進入未來,並從您的循環中完全消除睡眠。

你忘記取消上一個按鈕嗎?

編輯:你一次啓動10個線程,它們以未指定的順序執行。啓動一個單線程並將該循環放入線程的運行方法中。

+0

感謝您的回答,每個按鈕都會在我的真實代碼中執行很多http請求,睡眠或延遲不會有幫助,因爲我只想在http請求完成運行時離開按鈕,然後解除按鈕並移到下一個[附加的代碼不是我真實的代碼,只是例子] – kimo

+0

明白了。在附加到原始文章的示例中,我認爲,問題是您正在UI線程(在OnClickListener中)上執行所有昂貴的執行。應該將其移至工作線程,或者使用AsyncTask或您創建的線程。 –

0

您確定此代碼沒有崩潰。使用1到10之間的ID來獲取視圖對我來說看起來不好;)。您通常應該使用R.id類的整數。

其次你一定要用Handler s代替Thread。看看postDelayed方法。

+0

按鈕是動態創建的,我設置了每個按鈕的ID,並且它正在工作。 – kimo

0

爲什麼您使用ThreadHandler與對方! 我認爲這段代碼會更準確:

 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); 
     } 
+0

那不行。它將在循環運行後大約50毫秒的時間內運行所有可運行的程序。如果你做了'handler.postDelayed(runnable,500 * i)''',它會起作用。 –

+0

據我所知,它不會,它將延遲50從處理程序收到的最後一條消息,我會嘗試它,如果我有時間,並告訴你結果,但我已經有一個代碼告訴我,但不當然,因爲我沒有實現它 –