我試圖更新我的Android應用程序中幾個TextView
s的背景顏色。我想在這兩者之間設置每種顏色有短暫的停頓,即:在Android應用程序中更新短暫的睡眠背景顏色
<set TextView one's background to gold>
<pause 500ms>
<set TextView two's background to gold>
<pause 500ms>
<set TextView three's background to gold>
<pause 500ms>
的目標是使某種跨箱進步高亮模式。
我遇到的問題是所有的盒子在暫停後立即更新。我已經read that如果我想強制視圖繪製自己,我需要撥打invalidate()
,我已經嘗試過,但它似乎沒有做任何事情。我不確定是否我使用的睡眠方法導致了問題,或者如果我沒有用正確的方法強制繪製更新。希望有人能指出我朝着正確的方向:
Resources res = getResources();
for(int i=0; i<3; i++){
int id = res.getIdentifier("txt"+Integer.toString(box[i]), "id",
getApplicationContext().getPackageName());
TextView temp = (TextView)findViewById(id);
// Set gold with 50% opacity
temp.setBackgroundColor(Color.parseColor("#ffd700"));
temp.getBackground().setAlpha(127);
// Force redraw
temp.invalidate();
// Sleep for half a second
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
注:我想阻塞,直到背景的這個序列中的主要線索更改被更新,沒有什麼應該發生,直到這三個TextView
■找了更新,這就是爲什麼我從主UI線程調用sleep()
。
編輯
我試圖用一個可運行的,而「堵」我的主線程做背景的更新。如果這是應該說不定處理方式有人能指出我我要去哪裏錯了:
boolean moveon;
//...
onCreate() {
moveon = false;
//...
Handler myh = new Handler();
Runnable myr = new Runnable() {
public void run() {
Resources res = getResources();
for(int i=0; i<3; i++){
id = res.getIdentifier("txt"+Integer.toString(winners[i]), "id",
getApplicationContext().getPackageName());
TextView temp = (TextView)findViewById(id);
temp.setBackgroundColor(Color.parseColor("#ffd700"));
temp.getBackground().setAlpha(127);
temp.invalidate();
}
moveon = true;
}
};
myh.post(myr);
while(moveon == false){} //blocks forever here, perhaps the update to from the
// runable doesn't propagate?
「我希望主線程被阻止」 - 不,您希望在此期間禁用UI,而不是阻止,這就是爲什麼它們都是同時發生的原因。一個更好的選擇是全局布爾值,我們稱它爲「啓用」,並在操作期間將其設置爲false,然後在更新完成時將其設置爲true,同時從輔助線程調用postInvalidate()。然後在你的UI線程中,你應該檢查在允許任何額外的操作發生之前是否啓用等於真。這會造成被封鎖的幻覺,而不會被封鎖。 – Guardanis
@Guardanis - 將主UI線程放入一個無限的'while'循環中,等待全局更新,而不是讓它進入睡眠狀態? 「阻塞」,「禁用」,「停滯」......無論如何,只有在我需要的更新完成之後,它纔會移動。我看到,同樣的事情,我不明白爲什麼'invalidate()'不會導致UI的更新。我錯了嗎? – Mike
它實際上是更新UI,但onDraw(Canvas)調用在調用invalidate()後不會立即發生。系統會對它進行排隊,這似乎是在所有睡眠完成後發生的,因爲UI線程被睡眠呼叫阻塞。如果您檢查文檔無效,您應該注意以下行:「將在未來的某個時刻被調用。」 – Guardanis