我試圖從後臺線程向MapView添加一個疊加層以光學標記用戶當前正在觸摸的點。在觸摸事件期間從後臺線程更新UI
目前我嘗試使用定時器/處理程序實現該功能。 當MotionEvent爲ACTION_DOWN時,我發佈了一個任務,它在一定的延遲之後將圓形覆蓋圖添加到mapView覆蓋圖。
不幸的是,用戶界面僅在用戶從屏幕上移除手指(ACTION_UP)後纔會更新。
這裏的示例代碼:
UI線程
if (event.getAction() == MotionEvent.ACTION_DOWN) {
handler = new OverlayHandler(mapView, centerDrawer) // centerDrawer is an overlay drawing a circle
cTask = new DrawTimer(handler); // Calls handler.sendMessage, telling the handler to add centerDraw to the overlays of mapView
handler.postDelayed(cTast, delay);
} else {
handler.removeCallbacks(cTask);
}
定時器(DrawTimer等)
public void run() {
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
}
處理程序
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
mapView.getOverlays().add(centerDrawer);
break;
// more cases
}
super.handleMessage(msg);
}
據我所知,這是從後臺任務與UI交互的默認方式。
這對用戶在與屏幕交互時的更新有效嗎? 我是否必須明確告訴視圖才能渲染新的疊加層?
編輯:
代碼應做到以下幾點: 在觸摸,它應該開始觀察多久用戶保持接觸。初始延遲後,該圓應添加到視圖中。經過一段時間之後,又添加了一個覆蓋層,等等。
我這樣做,爲每個覆蓋分兩步: 我添加一個Runnable處理程序將延遲執行。 Runnable然後將相應的消息發送給處理程序,告訴它,要繪製什麼。 我做它喜歡,因爲......
- 我需要能夠取消計時器(後),如果用戶移動或釋放其手指。
- 當用戶持續觸摸屏幕時,一些覆蓋圖應該改變。 postDelayed Runnable只是不斷髮送消息直到取消。
這就是爲什麼我不只是使用延遲的消息。
使用案例
用戶觸摸屏幕 - >延遲過去之前用戶的版本(無應出現)
觸 - >延遲傳遞 - >圈子 - >釋放
觸控 - >延時通過 - >循環 - >延時2次 - >循環2 - >發佈
可運行在postDelayed添加的延遲後執行。然後(延遲之後)告訴Handler更新UI。我不會在隊列中發佈兩次相同的信息。 我需要這樣做,因爲如果用戶在延遲過去之前移開手指,我需要能夠取消繪圖。 我用這個信息澄清我的問題。 – PvB 2012-03-18 19:13:50
postDelayed()不是一個確切的計時器。 UI消息隊列處理事情,因爲它有時間這樣做,所以有可能例如您的兩條消息幾乎同時被處理。我不能說這是你的問題的原因,但它可能是你的代碼中的問題。您是否添加了日誌語句以查看您何時正在獲取ACTION_UP和ACTION_DOWN事件? – 2012-03-18 19:29:28
好吧,有趣的是,如果我使用sendMessageAtTime,則會在觸摸時出現圓。你可能是對的,Runnables有問題。我深入瞭解它,感謝您指出這一點! – PvB 2012-03-18 19:32:25