2013-05-27 145 views
1

我有一個GridLayout其中有幾個按鈕。更新UI而不凍結

我需要改變序列中每個按鈕的顏色,比方說,每3秒。

我有過一個問題在這裏...看看我的代碼:

runnableScan = new Runnable() { 
    @Override 
    public void run() { 
     GridLayout view = Grid; 
     for (int i = 0; i < view.getChildCount(); i++) { 
      Button btn = (Button)view.getChildAt(i); 
      btn.setBackgroundColor(Color.RED); 
      handlerScan.postDelayed(this, 3000);           
     } 
    } 
};  
handlerScan.postDelayed(runnableScan, 3000);  

嗯..它改變所有的按鈕,紅色的顏色,但一下子它改變了他們 !!!

我希望它改變顏色的順序,每3秒一個按鈕。

如果我在裏面放入ToastToast會每隔三秒觸發一次,每個按鈕的索引號。

我做錯了什麼?爲什麼所有按鈕都一次變成紅色?

+0

您確定「Toast」每3秒運行一次,但您沒有看到它,直到之前的「吐司」被解僱? – codeMagic

+0

從您發佈的代碼判斷,它實際上是一次更改所有按鈕的顏色。嘗試用Log.d替換Toast,並再次將時間與logcat條目進行比較。吐司可能會給你一種延遲的幻覺,因爲在第一道吐司被清除之前,第二道吐司纔會出現。 – TactMayers

+0

你好codeMagic和TactMayers!感謝您的反饋意見。事實上,Toast每三秒運行一次,並顯示每個按鈕的文本(索引)。由於Toast文字發生變化,我相信它會在每三秒鐘更改一次文字後觸發。有任何想法嗎? –

回答

0

Runnable的run()方法仍是遍歷所有按鈕,和一個呼叫run()過程中改變對他們的所有顏色。

這條線:

handlerScan.postDelayed(this, 3000);           

不加for循環迭代之間的延遲。它只安排run()在3秒後再次被調用。試試這個(否循環)。

runnableScan = new Runnable() { 
    @Override 
    public void run() { 

     GridLayout view = Grid; 
     Button btn = (Button)view.getChildAt(buttonIndex++); 
     if (btn != null) { 
      btn.setBackgroundColor(Color.RED); 
      handlerScan.postDelayed(this, 3000); 
     } 
    } 
    }; 
    handlerScan.postDelayed(runnableScan, 3000); 

你需要跟蹤buttonIndex作爲類的成員變量:

private int buttonIndex; 

,然後將其初始化爲你的第一個按鈕的索引。例如,如果您設置的內容視圖中onCreate(),然後使用:

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.some_layout_name); 

     GridLayout view = Grid; 
     for (buttonIndex = 0; buttonIndex < view.getChildCount(); buttonIndex++) { 
     View v = view.getChildAt(buttonIndex); 
     if (v instanceof Button) { 
      // we found the first button, so stop looping 
      break; 
     } 
     } 

     handlerScan = new Handler(); 

的方式我給你工作的代碼是,它會改變按鈕1的顏色爲紅色,然後3秒後,換按鈕2紅色,然後3秒鐘後,將按鈕3更改爲紅色。如果您想重新啓動該過程,只需將buttonIndex重新設置回第一個按鈕的索引,並在完成更改按鈕3後即可。

+0

你好Nate ...首先,感謝您的回答。這很有道理。我只是編輯我的代碼來反映你的提示。但即便如此,似乎我的代碼等待三秒鐘,然後,它將所有按鈕更改爲紅色。注意我插入了這個:handlerScan.postDelayed(this,3000);在循環內。即使如此,它會一次將所有按鈕變爲紅色。有任何想法嗎?這讓我瘋狂! = P –

+0

你沒有做我以前的建議。你仍然在循環所有3個按鈕。我修改了我的答案,以顯示**完全**您應該使用什麼。 – Nate

+0

你好Nate!非常感謝你!這就是訣竅!此外,我剛剛瞭解了更多關於處理程序如何在Android中工作的信息!謝謝! –