我试图从后台线程向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