Home » Android » java – How update markers on Map when using ClusterManager

java – How update markers on Map when using ClusterManager

Posted by: admin June 15, 2020 Leave a comment

Questions:

I am trying to update my map with newer data from server but I can’t figure out how to remove old items (markers and cluster – Using ClusterManager) from map ( – seems to me that I can only add in ClusterManager.

I have BroadcastReceiver which get intent when there are new data. I was trying something like this: ( but it gives me UnsupportedOperationException on line with “…getMarkers().clear();”

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());
    }
};

I added data to map only with this function.

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());
How to&Answers:

According to ClusterManager documentation, we can use mClusterManager.cluster();

This method Force a re-cluster. You may want to call this after adding
new item(s).

Answer:

I was concentrating the whole time on ClusterManager, so I forgot about GoogleMap, and specifically the method clear(). I was able to solve the problem with this code:

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

Answer:

There isn’t any API to notify that a cluster item has been updated.
But you can use clusterManager.removeItem() + clusterManager.addItem() to force an update to an item.

But you must be careful, as you normally want to update an item because it has changed some properties that affect rendering you need to use a custom ClusterRenderer that supports this and overrides onClusterItemRendered() and/or onClusterRendered(). Using the onBefore variants wont work because they are only called once on marker creation.

You can look at this GitHub issue GitHub issue

Answer:

Since my app needs to update the clusters multiple times after the map is created, I found this workflow as the best solution to remove and add new clusters:

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

That should force the clusters to rerender after modifying the contents.

Answer:

What worked for me was not clear()the map, because I have some other markers not attached to the cluster manager.

What worked for me is:

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()

Answer:

I was wondering how I could have had this problem – I’ve never ran into issues like this before with map nodes.

However, this was in my sample app’s set-up-or-update-map logic:

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

I was adding nodes from a db then also some nodes from a request, there was a noticeable impact until I added a null check for the constructor

i.e., this is how I should have had it:

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

I must have copied and pasted this and wasted half an hour on that .. watch out!