dudeguy
dudeguy

Reputation: 67

Android Google Maps SDK Multiple MarkerClickListener

TL;DR - what happens if you try and apply a MarkerClickListener on the same markers twice? Is the first one cancelled out? Are they both active? Will this cause issues?

We have a project that uses the Google Maps SDK and the android-maps-utils for various items.

  1. We are using the GeoJson feature of the android-maps-utils --and--
  2. We are using the MarkerManager of the android-maps-utls

On map load, we load all of our features including markers, cluster items, and GeoJson (lines) to the map.

When you apply the .setOnFeatureClickListener() for the GeoJson feature set (lines), it applies a click listener for every item on the map. Per the source code:

    /**
 * Sets a single click listener for the entire GoogleMap object, that will be called
 * with the corresponding Feature object when an object on the map (Polygon,
 * Marker, Polyline) is clicked.
 * <p>
 * If getFeature() returns null this means that either the object is inside a KMLContainer,
 * or the object is a MultiPolygon, MultiLineString or MultiPoint and must
 * be handled differently.
 *
 * @param listener Listener providing the onFeatureClick method to call.
 */
public void setOnFeatureClickListener(final OnFeatureClickListener listener) {

    GoogleMap map = getMap();

    map.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
        @Override
        public void onPolygonClick(Polygon polygon) {
            if (getFeature(polygon) != null) {
                listener.onFeatureClick(getFeature(polygon));
            } else if (getContainerFeature(polygon) != null) {
                listener.onFeatureClick(getContainerFeature(polygon));
            } else {
                listener.onFeatureClick(getFeature(multiObjectHandler(polygon)));
            }
        }
    });

    map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(Marker marker) {
            if (getFeature(marker) != null) {
                listener.onFeatureClick(getFeature(marker));
            } else if (getContainerFeature(marker) != null) {
                listener.onFeatureClick(getContainerFeature(marker));
            } else {
                listener.onFeatureClick(getFeature(multiObjectHandler(marker)));
            }
            return false;
        }
    });

    map.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
        @Override
        public void onPolylineClick(Polyline polyline) {
            if (getFeature(polyline) != null) {
                listener.onFeatureClick(getFeature(polyline));
            } else if (getContainerFeature(polyline) != null) {
                listener.onFeatureClick(getContainerFeature(polyline));
            } else {
                listener.onFeatureClick(getFeature(multiObjectHandler(polyline)));
            }
        }
    });
}

The problem is, I dont want to use the map.setOnMarkerClickListener() for the markers that the setOnFeatureClickListener() applies, we need the MarkerManager to apply the marker listener. So we are doing that as well:

   public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mLineLayer.setOnFeatureClickListener(new GeoJsonLayer.OnFeatureClickListener() {
            @Override
            public void onFeatureClick(Feature feature) {

                GeoJsonLineStringStyle lineStringStyle = new GeoJsonLineStringStyle();
                GeoJsonFeature lineStringFeature = (GeoJsonFeature) feature;
                lineStringStyle.setColor(Color.RED);
                lineStringStyle.setWidth(14);
                lineStringFeature.setLineStringStyle(lineStringStyle);
            }
        });

    mMarkerManager = new MarkerManager(mMap);
    mMap.setOnMarkerClickListener(mMarkerManager);

    CachedCollection.instance().setupCollection(mMarkerManager);
    mCollection = CachedCollection.instance().getCollection();

    mCollection.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(Marker marker) {

            doSomething(marker)

            return true;
        }
    });
}

The code above works, as long as we have the Feature click listener set first. It breaks if we have the Feature click listener set second.

I think its applying the marker click listener once, then it sets/resets it when the markermanager sets the listener. The problem is, I don't know if that's true.

Are there 2 listeners now? Will this cause some memory leak issue? Is there anything we can do to workaround this? I dont want to modify the android-maps-utils library.

Upvotes: 2

Views: 361

Answers (1)

Andrii Omelchenko
Andrii Omelchenko

Reputation: 13343

what happens if you try and apply a MarkerClickListener on the same markers twice?

current listener will be replaced by new

Is the first one cancelled out?

yes, its replaced by new

Are they both active?

no, "old" listener replaced by new

Will this cause issues?

it depends on your code. Mostly - no.

Is there anything we can do to workaround this?

you can use setTag() method of Marker class to associate an ID corresponding to the marker kind and then get it in onMarkerClick(Marker marker) via getTag() method and call correspond methods for marker kinds:

...
@Override
public boolean onMarkerClick(Marker marker) {
    MarkerKind kind = (MarkerKind) marker.getTag();
    if (kind.id == MARKER_KIND1) {
        doSomething(marker);
    } else {
        doSomethingElse(marker);
    }
    return true;
}
...

Upvotes: 1

Related Questions