I have a google maps in my android app. It is full of markers, it clusters the markers... in a few words, a fully usable map.
What i want to do it's simple. When user tap on clusterItem, I want to change the icon to a selected one. (simply, same marker but with different color).
How I am using a lot of markers on screen, It's imposible to clean the map and add the markers everytime a mark is clicked.
So:
mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
@Override
public boolean onClusterItemClick(MyItem myItem) {
if (oldItemSelected != null) {
mClusterManager.removeItem(oldItemSelected);
oldItemSelected.setItemAsNotSelected();
mClusterManager.addItem(oldItemSelected);
}
mClusterManager.removeItem(myItem);
myItem.setItemAsSelected();
mClusterManager.addItem(myItem);
mClusterManager.cluster();
oldItemSelected = myItem;
return true;
}
});
The idea is to remove the item clicked from the map, set it to "selected", add the new item and refresh the map with .cluster method.
What happens: The item doesn't change, sometimes the item is "duplicated" and the selected is behind the "normal" item.
This is how I set up cluster manager:
mClusterManager = new ClusterManager<MyItem>(this, map);
mClusterManager.setRenderer(new MyItemRenderer());
mClusterManager.setAlgorithm(new GridBasedAlgorithm<MyItem>());
map.setOnMarkerClickListener(mClusterManager);
And this is the item renderer:
private class MyItemRenderer extends DefaultClusterRenderer<MyItem> {
public MyItemRenderer() {
super(getApplicationContext(), map, mClusterManager);
}
@Override
protected void onBeforeClusterItemRendered(MyItem myItem, MarkerOptions markerOptions) {
markerOptions.title(myItem.getName());
markerOptions.snippet(myItem.getAddress());
markerOptions.icon(BitmapDescriptorFactory.fromResource(myItem.getIcon()));
}
@Override
protected boolean shouldRenderAsCluster(Cluster cluster) {
return cluster.getSize() > 1;
}
public Marker getMarker(MyItem item) {
return super.getMarker(item);
}
}
Is there any way to do this without having to re-paint every item in the map?
public class MyItem extends DefaultClusterRenderer<WifiSpotItem> {
private HashMap<Integer, Marker> markerWifiSpots = new HashMap<>();
public MyItem(Context context, GoogleMap map, ClusterManager<WifiSpotItem> mClusterManager) {
super(context, map, mClusterManager);
}
@Override
protected void onBeforeClusterItemRendered(WifiSpotItem wifiSpotItem, MarkerOptions markerOptions) {
if (markerOptions != null && wifiSpotItem != null) {
markerOptions.title(wifiSpotItem.getName() != null ? wifiSpotItem.getName() : Constants.EMPTY_STRING);
markerOptions.snippet(wifiSpotItem.getAddress() != null ? wifiSpotItem.getAddress() : Constants.EMPTY_STRING);
markerOptions.icon(BitmapDescriptorFactory.fromResource(wifiSpotItem.getIcon()));
}
}
@Override
protected void onClusterItemRendered(WifiSpotItem clusterItem, Marker marker) {
markerWifiSpots.put(clusterItem.getId(), marker);
super.onClusterItemRendered(clusterItem, marker);
}
@Override
protected boolean shouldRenderAsCluster(Cluster cluster) {
return cluster.getSize() > 4;
}
public Marker getMarker(WifiSpotItem item) {
return super.getMarker(item);
}
public Marker getMarker(int id) {
Marker item;
if (markerWifiSpots != null) {
item = markerWifiSpots.get(id);
} else {
item = null;
}
return item;
}
}
Seems that render task ignores objects which have been already displayed on the screen. I tried to add new instance of MyItem
object (copy of onClusterItemClick
method argument) to the cluster manager and it works.
mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
@Override
public boolean onClusterItemClick(MyItem myItem) {
...
mClusterManager.removeItem(myItem);
MyItem copy = myItem.copy();
copy.setItemAsSelected();
mClusterManager.addItem(copy);
mClusterManager.cluster();
...
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With