我正在尝试从后台线程向MapView添加叠加层,以光学标记用户当前正在触摸的点。
目前我尝试使用Timer / Handler实现这一目标。 当MotionEvent是ACTION_DOWN时,我发布一个任务,在一定的延迟后将圆形叠加添加到mapView叠加层。
不幸的是,只有在用户从屏幕上移开手指后才会更新UI(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然后将相应的消息发送给处理程序,告诉它,绘制什么。 我这样做,因为......
这就是为什么我不只是使用延迟信息。
使用案例
用户触摸屏幕 - >用户在延迟通过之前释放(不应出现任何内容)
触摸 - >延迟通过 - >圈子 - >释放
触摸 - >延迟通过 - >圈子 - >延迟2次通过 - >圈2 - >释放
答案 0 :(得分:2)
您的评论说“调用handler.sendMessage ...”,但随后您将延迟发布到处理程序。你要么想要调用sendMessage,要么调用postDelayed,而不是两者。你把消息放在队列2x上。但这并不一定能解释你的问题。
你应该发布DelayTimer的代码,并检查延迟的值。
答案 1 :(得分:0)
在这个问题中找到答案: Views Don't Update Until MapView is Touched
mapView.invalidate()强制视图重绘其所有叠加层。它可能不是实现该行为的最有效方式,但它以我想要的方式工作。
感谢farble1670指出我之前实现的一些问题。 根据他的建议,我将其更改为仅使用消息(使用removeMessage也可以取消)。
新代码更简单:
用户界限线程
if (event.getAction() == MotionEvent.ACTION_DOWN) {
handler = new OverlayHandler(mapView, centerDrawer)
handler.sendEmptyMessageDelayed(1, d);
} else {
handler.removeMessage(1);
}
<强>处理程序强>
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
mapView.getOverlays().add(centerDrawer);
break;
// more cases
}
mapView.invalidate(); // Forces redrawing of all overlays
super.handleMessage(msg);
}