Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue refreshing markers #63

Closed
daschewie opened this issue Feb 27, 2014 · 15 comments
Closed

Issue refreshing markers #63

daschewie opened this issue Feb 27, 2014 · 15 comments
Labels
Milestone

Comments

@daschewie
Copy link

I am trying to change the icon for a selected marker. Neither calling ClusterManager.cluster, nor MapView.invalidate will cause the ClusterRenderer to render new pins.

protected void onBeforeClusterItemRendered(FacilityClusterItem item, MarkerOptions markerOptions) {
        Facility facility = item.getFacility();

        int pinId = 0;

        if (TextUtils.equals(facility.getId(), mSelectedFacilityId)) {
            mIconGenerator.setBackground(mContext.getResources().getDrawable(R.drawable.map_pin_white));
            pinId = facility.getFacilityType().getSelectedMapPinId();
        } else {
            mIconGenerator.setBackground(mContext.getResources().getDrawable(R.drawable.map_pin_purple));
            pinId = facility.getFacilityType().getMapPinId();
        }

        icon = BitmapDescriptorFactory.fromResource(pinId);
        markerOptions.icon(icon);
    }
@jakeonrails
Copy link
Contributor

I think this is because this callback happens prior to a cluster item map marker being added to the map object.

So you only get to override the icon once, right when the marker is created for the first time.

To get the item to update you'd have to remove it and add it back, I think.

I did something different, I manually overrode the callback for the cluster manager's marker items:

clusterManager.getMarkerCollection().setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
  @Override
  public boolean onMarkerClick(Marker marker) {
    BitmapDescriptor icon = ...;
    marker.setIcon(icon);
  }
}

Although I am currently debugging some issues with this approach, where when that marker whose icon has been set with setIcon gets removed from the map (via clusterManager.clear() or some other means), the application crashes with an error due to a java.lang.IllegalArgumentException: Released unknown bitmap reference.

@artworkad
Copy link

@jakeonrails @daschewie may be related #90

@Shusshu
Copy link

Shusshu commented Aug 8, 2014

This is also my use case.
"Changing the selected marker's icon"

Any stable way to achieve this?

@Shusshu
Copy link

Shusshu commented Aug 11, 2014

This commit makes it possible: 49d42d6

@hermannloose
Copy link

@jakeonrails You can theoretically override onClusterItemRendered to achieve this, which allows you to set the icon on the existing Marker instead of MarkerOptions. The gotcha with this approach is that the call happens as part of CreateMarkerTask#perform which should run as part of the RenderTask; only the latter does not actually do anything if the sets of clusters did not change, according to equals. Now, this should be fine if you're diligent in overriding equals for your class implementing ClusterItem, only ClusterManager#setAlgorithm decides that it will slap a PreCachingAlgorithmDecorator on whatever you pass in (not that you asked for it), so that as far as I can see you cannot ever hope to convince the renderer that yes, in fact your clusters have changed ...

So what I think we really want is for ClusterManager to not try and be too clever about enhancing the algorithm you pass in, if the decorator actually breaks behaviour.

@darekdeo
Copy link

java.lang.IllegalArgumentException: Released unknown imageData reference
at com.google.a.a.ae.a(Unknown Source)
at com.google.maps.api.android.lib6.e.dn.c(Unknown Source)
at com.google.maps.api.android.lib6.e.ag.o(Unknown Source)
at com.google.maps.api.android.lib6.e.ag.a(Unknown Source)
at com.google.android.gms.maps.model.a.p.onTransact(SourceFile:51)
at android.os.Binder.transact(Binder.java:380)
at com.google.android.gms.maps.model.internal.zzf$zza$zza.remove(Unknown Source)
at com.google.android.gms.maps.model.Marker.remove(Unknown Source)
at com.google.maps.android.MarkerManager$Collection.remove(MarkerManager.java:163)
at com.google.maps.android.MarkerManager.remove(MarkerManager.java:140)
at com.google.maps.android.clustering.view.DefaultClusterRenderer$AnimationTask.onAnimationEnd(DefaultClusterRenderer.java:912)
at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1089)
at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:666)
at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:682)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:549)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5297)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)

Getting above error while using onClusterItemRendered. I am running async task to get image for marker:

protected void onClusterItemRendered(Poi clusterItem, Marker marker) {
    super.onClusterItemRendered(clusterItem, marker);

    try {
        URL url = new URL(clusterItem.getImage());
        AsyncDownloadImage async = new AsyncDownloadImage(marker);
        async.execute(url);
    } catch (MalformedURLException e) {
        Log.e("CluserRenderer", "Wrong url address: " + clusterItem.getImage());
    }
}

And in onPostExecute I do this (markerReference is WeakReference):

protected void onPostExecute(final Bitmap bitmap) {

    Marker marker = markerReference.get();

    if (bitmap != null && marker != null) {
        mImageView.setImageBitmap(bitmap);
        Bitmap icon = mIconGenerator.makeIcon();
        try {
            marker.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
        } catch (IllegalArgumentException e) {
            Log.e("ClusterRenderer", "Couldn't set icon.");
        }
    }
}

Images for marker cluster items do render while zooming in, then while zooming out the cluster group is rendered for marker, then again while zooming in items do render correctly. Exception occurs when user do zoom in and zoom out fast when items did not render yet.

@darekdeo
Copy link

Keeping marker object instead of weakreference in async fixed issue for me. Additionaly I keep hashmap of already downloaded url/ bitmap in ClusterRenderer class. Whenever clusteritem gets rendered it checks hashmap for bitmaps.

@darekdeo
Copy link

Nope, still crashes, same error as before.

@ShawnDuan
Copy link

@darekdeo +1

@Jogan
Copy link

Jogan commented Mar 24, 2016

Currently working on same issue hopefully can figure something out.

@stephenmcbride
Copy link

I managed to get this working for showing a selected state on a marker. It requires extending the DefaultClusterRenderer class and overriding one method (onBeforeClusterItemRendered) and adding an onClusterItemClick listener.

public class MyCustomRenderer<T> extends DefaultClusterRenderer implements ClusterManager.OnClusterItemClickListener<MyClusterItem> {

private MyClusterItem currentClickedClusterItem;

public MyCustomRenderer(Context context, GoogleMap map, ClusterManager<MyClusterItem> clusterManager) {
    super(context, map, clusterManager);
    setOnClusterItemClickListener(this);
}

@Override
protected void onBeforeClusterItemRendered(ClusterItem item, MarkerOptions markerOptions) {
    if (currentClickedClusterItem != null && item.equals(currentClickedClusterItem)) {
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
    } else {
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    }

}

@Override
public boolean onClusterItemClick(MyClusterItem item) {

    if (currentClickedClusterItem != null) {
        getMarker(currentClickedStopItem).setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    }
    currentClickedStopItem = item;
    getMarker(item).setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
    return true;
}
}

@SimonHaenle2
Copy link

getMarker() always returns null for me, no way to get this working...

@stale
Copy link

stale bot commented Oct 3, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the status: will not fix Invalid (untrue/unsound/erroneous), inconsistent with product, not on roadmap. label Oct 3, 2019
@jpoehnelt jpoehnelt removed the status: will not fix Invalid (untrue/unsound/erroneous), inconsistent with product, not on roadmap. label Oct 3, 2019
@stale
Copy link

stale bot commented Jan 1, 2020

This issue has been automatically marked as stale because it has not had recent activity. Please comment here if it is still valid so that we can reprioritize. Thank you!

@stale stale bot added the stale label Jan 1, 2020
@arriolac arriolac added the triage me I really want to be triaged. label Jan 29, 2020
@stale stale bot removed the stale label Jan 29, 2020
@arriolac
Copy link
Contributor

Duplicate of #90, closing this issue in favor of that one instead. See the discussion there for possible workarounds in the meantime.

@arriolac arriolac added status: duplicate Duplicate. and removed triage me I really want to be triaged. labels Jan 29, 2020
@arriolac arriolac added this to the 1.0 milestone Feb 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests