谷歌地图API V2添加标记和OnCameraChangeListener

3

场景

  • 读取用户的初始位置并添加标记,设置相机位置为该位置。
  • 每次用户拖动/缩放相机时,需要调用Web服务并传递地图的矩形坐标。此Web服务将返回地图范围内要显示为标记的位置列表。

因此,基本上我正在做以下操作:

onCreate

mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        // Make a web call for the locations
        myTask = new MyTask();
        myTask.execute();
}

在每个从Web服务返回的项目上,我都会执行任务 onPostExecute

mMap.addMarker(
    new MarkerOptions().position(
        new LatLng(myPoint.getLatitude(), myPoint.getLongitude())
    )
    .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_pushpin))
);

期望的行为: 每次用户滚动或缩放时,相机位置都会改变,并且异步任务会再次被调用以获取一组新的活动坐标。

实际的行为: onPostExecuteOnCameraChangeListener之间发生无限循环。

据我所知,但也可能我是错的,addMarker触发了相机位置变化事件?如何才能实现上述期望的行为?

2个回答

4

在我看来,但也许我错了,addMarker会触发相机更改事件吗?

不会。您可能需要添加完整的代码供其他人尝试解决这个难题。

期望的行为:每次用户滚动或缩放时,相机位置都会更改,并且异步任务会再次被调用以获取一批新的活动坐标

为什么要在用户更改相机位置时每次获取相同的数据?

一些考虑可以改善用户体验:

  • 只获取所有数据一次并将它们存储到SQLite数据库中。当然,如果数据发生更改,您需要同步它们,这可能需要稍微更改webservice。不要在简单的用户界面更改时下载所有内容。
  • 保持webservice通信在Activity上下文之外,以获得无内存泄漏的解决方案。如果您将MyTask作为Activity内部类,这将使销毁的Activity一直存在于内存中,直到任务完成。
  • 仅在可见区域添加标记,并且如果已经添加了标记,则不要将它们删除。标记数量将继续增长,但这比每次用户移动地图时调用clear()要好。像CommonsWare正确建议的那样:越少的IPC越好。为此,我可以建议使用Android Maps Extensions。即使您不使用标记聚类,它也有一个选项可以动态添加标记,因此您不需要自己编写代码。

感谢确认addMarker不会触发相机更新的事实。我再仔细查看了一下我的代码,发现了问题(一个错误的活动重启:))。关于标记的问题是,它们大部分时间都是动态的,这就是为什么我需要重新读取它们所有内容的原因。 - Alin
@Alin 大部分时间是多久?标记代表人吗?仍然不好使用onCameraChange触发。用户不必长时间互动,或者可以疯狂地滑动以查看南极洲上有哪些标记。在X分钟/小时/天内获取数据更新可能更好。当然,轮询永远无法击败推送。 - MaciejGórski
项目规格如下:当用户滑动/缩放或每30秒时,获取标记。这些标记是汽车。问题在于,Web服务仅返回可见坐标的数据,因此如果我稍微拖出一点,我需要更新其余的标记+显示新的标记。据我所见,唯一的方法就是每次调用Web服务。我相信标记大约有10-15个。该应用程序非常特定,仅将在某些城市中使用,因此用户无需缩小/滑动太多。 - Alin

1

我该如何实现上述所描述的预期行为?

首先,只有在数据与上一个任务不同时才调用MyTask。如果没有实际的摄像头更改,则坐标应与上一个任务相同,您不需要再次访问服务器。

其次,只添加尚未在地图上的标记(并且不要删除已经删除的标记)。即使存在前一步骤无法解决的微小摄像头更改,这些更改也不太可能导致标记的排列发生变化。我假设您当前的逻辑是清除所有标记并重新加载它们,而这并不特别高效,无论这种摄像机更改行为如何。几乎任何对GoogleMap的调用都涉及IPC,因此您希望尽可能少地进行这些调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接