我试图更新我的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