当使用ClusterManager时如何更新地图上的标记?

10
我试图使用来自服务器的新数据更新我的地图,但是我无法弄清如何从地图中删除旧项目(标记和集群-使用ClusterManager) - 似乎我只能在ClusterManager中添加。
我有一个广播接收器,当有新数据时会收到意图。我尝试了这样的代码:(但是在“... getMarkers()。clear();”一行上给我UnsupportedOperationException)。
private BroadcastReceiver myRefrestMapBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive");
        mClusterManager.clearItems();
        mClusterManager.getMarkerCollection().getMarkers().clear();
        mClusterManager.getClusterMarkerCollection().getMarkers().clear();
        mClusterManager.addItems(LocationGetter.getReports());
    }
};

我只使用了这个函数向地图中添加数据。
java.util.Collection<Marker> userCollection = mClusterManager.getMarkerCollection().getMarkers();
            ArrayList<Marker> userList = new ArrayList<Marker>(userCollection);
            // now is userList empty
            for(Marker marker: userList){
                marker.remove();
            }

            java.util.Collection<Marker> userCollection2 = mClusterManager.getClusterMarkerCollection().getMarkers();
            ArrayList<Marker> userList2 = new ArrayList<Marker>(userCollection2);
            // now is userList2 empty
            for(Marker marker: userList2){
                marker.remove();
            }

            mClusterManager.addItems(LocationGetter.getReports());

我在这里使用了这个方法。如果你得到了空的ArrayList,请确保你有正确的ClusterManagerMarkerCollection() - bjiang
7个回答

11
根据 ClusterManager文档,我们可以使用 mClusterManager.cluster();

该方法强制重新聚类。在添加新项后,您可能需要调用此方法。


当使用多个项目时,如何删除特定项目?请您看一下这篇文章 https://dev59.com/Ha_la4cB1Zd3GeqP0vX- ?? - Queendevelopers

10

我一直在专注于ClusterManager,所以忘记了GoogleMap,尤其是clear()方法。我能够使用以下代码解决问题:

mGoogleMap.clear();
mClusterManager.clearItems();  // calling just in case (may not be needed)
mClusterManager.addItems(LocationGetter.getReports());

4
对我来说这还不够。我删除和添加了很多项目。在操作完成后调用此方法解决了缺失刷新的问题: mClusterManager.cluster(); 或许对某些人有帮助。 - plexus
正如 @plexus 所说,需要调用 cluster() 来确保集群已更新。而且要小心使用 .clear(),因为很多时候你需要缩放地图以使其正确更新。 - lujop

5

没有任何API可以通知集群项已更新。但是您可以使用clusterManager.removeItem() + clusterManager.addItem()来强制更新项目。

但是您必须小心,因为通常要更新项目是因为它已更改了一些影响呈现的属性,您需要使用自定义ClusterRenderer来支持此操作,并覆盖onClusterItemRendered()和/或onClusterRendered()。使用onBefore变量将不起作用,因为它们仅在标记创建时调用一次。

您可以查看这个GitHub问题GitHub issue


请您看一下这篇文章 https://dev59.com/Ha_la4cB1Zd3GeqP0vX- - Queendevelopers

4

由于我的应用程序需要在创建地图之后多次更新聚类,我发现这个工作流程是删除和添加新聚类的最佳解决方案:

mGoogleMap.clear();
mClusterManager.clear(); 
//Do work to add items to cluster
mClusterManager.addItems(yourItemsList);
//Finally 
mClusterManager.cluster(); 

那应该强制集群在修改内容后重新渲染。

1

我采用的方法不是清空地图(clear()),因为我还有一些没有附加到聚合管理器的标记。

我的解决方案是:

this.clustermanger.clearItems()
this.clustermanager.clusterMakerCollection.clear()
//and I had to force a "cluster" again, force the clustermanager to take down all markers
this.clustermanager.cluster()

1

你应该能够做到以下事情:

val didUpdate = clusterManager?.updateItem(MyClusterItem(data))
clusterManager?.cluster()

在这里确保clusterManager实际更新项的关键是要在扩展ClusterItem的类中覆盖equals和hashcode方法,例如:

fun getId(): String {
    return data.id
}
override fun equals(other: Any?): Boolean {
    return other is MyClusterItem && other.getId() == getId()
}
override fun hashCode(): Int {
    return getId().hashCode()
}

0
我在想我为什么会遇到这个问题 - 我以前从未遇到过与地图节点类似的问题。 然而,这是在我的示例应用程序的设置或更新地图逻辑中发生的:
        mClusterManager = new ClusterManager<>(getContext(), googleMap);
        mClusterManager.setAnimation(false);
        mClusterManager.clearItems();

我正在从数据库中添加节点,然后还从请求中添加了一些节点,直到我为构造函数添加了空值检查,才有明显的影响。

也就是说,我应该这样做:

    if (mClusterManager == null)
            mClusterManager = new ClusterManager<>(getContext(), googleMap);
        mClusterManager.setAnimation(false);
        mClusterManager.clearItems();

我一定是复制粘贴了这个,浪费了半个小时的时间...小心!


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