google-maps-clustering icon indicating copy to clipboard operation
google-maps-clustering copied to clipboard

Add possibility to change icon of selected marker

Open AleksandrTabolin opened this issue 7 years ago • 4 comments

Hi! Thank you for your work!

In app I work on I need to change icon of marker after clicked on it (make it bigger) . Now it's logic sealed in ClusterRenderer class, and there is no any posobility to change that. Easiest way to do it is add Marker from onMarkerClick method to methods of ClusterManager.Callbacks

AleksandrTabolin avatar Mar 06 '18 18:03 AleksandrTabolin

public interface RenderPostProcessor<T extends ClusterItem> {
    boolean postProcess(@NonNull Marker marker, @NonNull Cluster<T> cluster);
}
public class MarkerState {

    private final Marker marker;
    private boolean isDirty;

    public MarkerState(@NonNull Marker marker, boolean isDirty) {
        this.marker = marker;
        this.isDirty = isDirty;
    }

    public MarkerState(@NonNull Marker marker) {
        this(marker, false);
    }

    @NonNull
    public Marker getMarker() {
        return marker;
    }

    public boolean isDirty() {
        return isDirty;
    }

    public void setDirty(boolean dirty) {
        isDirty = dirty;
    } 
}

in ClusterRenderer change

    private final Map<Cluster<T>, Marker> mMarkers = new HashMap<>();

to

    private final Map<Cluster<T>, MarkerState> mMarkers = new HashMap<>();

and append this to ClusterRenderer.render

void render(@NonNull List<Cluster<T>> clusters) {
        ...

        for (Map.Entry<Cluster<T>, MarkerState> item : mMarkers.entrySet()) {
            Cluster<T> cluster = item.getKey();
            MarkerState markerState = item.getValue();

            boolean isPostProcessed = mRenderPostProcessor.postProcess(markerState.getMarker(), cluster);
            if (isPostProcessed) {
                markerState.setDirty(true);
            } else if (markerState.isDirty()) {
                // there should be reset to non-dirty state
                markerState.getMarker().setIcon(getMarkerIcon(cluster));
                markerState.setDirty(false);
            }
        }
    }

and then you can do something like this

setRenderPostProcessor { marker, cluster ->
                        selectedPoint?.let { point ->
                            val needProcess = cluster.latitude == point.latitude && cluster.longitude == cluster.longitude
                            if (needProcess) {
                                val icon = if (cluster.items.size == 1) {
                                    context.bitmapDescriptorFromVector(R.drawable.ic_map_pin_active)
                                } else {
                                    BitmapDescriptorFactory
                                            .fromBitmap(selectedClusterIconGenerator.makeIcon(cluster.items.size.toString()))
                                }
                                marker.setIcon(icon)
                            }
                            needProcess
                        } ?: false
                    }

AleksandrTabolin avatar Mar 14 '18 11:03 AleksandrTabolin

@AleksandrTabolin hi! Do you have this code published somewhere as a fork?

charlag avatar Mar 28 '18 14:03 charlag

@charlag Hi! Here link to fork.

AleksandrTabolin avatar May 08 '18 12:05 AleksandrTabolin

i dont know if you will reply but i just want to change the color of the cluster marker from red to black and keep the number as it is. i did try to usedefaultIconGenerator.setIconStyle(iconStyle); but i dont knw its not working srry but im new to android and cant figure it out by myself and had to ask

ak004 avatar May 01 '22 10:05 ak004