ClusterManager Repaint marqueurs de Google maps v2 utils
Salut Im faisant une requête de serveur et quand j'ai reçu la requête de serveur, j'exécute sur Ui Thread un ClusterManager.addItem () mais ces éléments ne sont pas peints dans la carte, seulement quand je fais une mise à jour de zoom ( + , -) sont affichés. Aussi, j'ai essayé de déboguer le renderer, mais onBeforeClusterRendered / onBeforeClusterItemRendered ne sont pas appelés jusqu'à ce que je mette à jour le zoom dans la carte. Des idées pour rafraîchir la carte / clusterManager / marqueurs?
MarkerManager markerManager = new MarkerManager(map);
clusterManager = new ClusterManager<TweetClusterItem>(getActivity(), map, markerManager);
clusterManager.setRenderer(new TweetClusterRenderer(getActivity(), map, clusterManager, defaultMarker));
clusterManager.setOnClusterClickListener(this);
clusterManager.setOnClusterInfoWindowClickListener(this);
clusterManager.setOnClusterItemClickListener(this);
clusterManager.setOnClusterItemInfoWindowClickListener(this);
UiSettings uiSettings = map.getUiSettings();
uiSettings.setZoomControlsEnabled(true);
uiSettings.setMyLocationButtonEnabled(false);
map.setOnCameraChangeListener(clusterManager);
map.setOnMarkerClickListener(clusterManager);
map.setOnInfoWindowClickListener(clusterManager);
map.setOnMapClickListener(this);
7 réponses
mClusterManager.cluster ();
force de re-classification des éléments lorsque vous après avoir ajouté un nouvel élément.
Semble que j'en ai trouvé une solution de contournement.
ClusterManager utilise un renderer, dans ce cas il hérite de DefaultClusterRenderer qui utilise un cache interne, un cache de marqueurs qui sont ajoutés à la carte. Vous pouvez accéder directement aux marqueurs ajoutés sur la carte, je n'utilise pas la fenêtre info, donc j'ajoute des options de marqueur.titre() un ID pour trouver plus tard ce marqueur, de sorte que:
@Override
protected void onBeforeClusterItemRendered(TweetClusterItem item, MarkerOptions markerOptions) {
.... Blabla code....
markerOptions.title(Long.toString(tweet.getId()));
.... Blabla code....
}
et quand je veux recharger la clusterItem j'appelle cette méthode:
/**
* Workarround to repaint markers
* @param item item to repaint
*/
public void reloadMarker(TweetClusterItem item) {
MarkerManager.Collection markerCollection = clusterManager.getMarkerCollection();
Collection<Marker> markers = markerCollection.getMarkers();
String strId = Long.toString(item.getTweet().getId());
for (Marker m : markers) {
if (strId.equals(m.getTitle())) {
m.setIcon( ICON TO SET);
break;
}
}
}
Peut-être est un peu hacky mais ça marche et je n'ai pas trouvé d'autre moyen de faire ça. Si vous avez trouvé un autre meilleur, merci de partager :)
j'ai eu le même problème. Il a également été aggravé par le fait que je fais un rendu personnalisé dans onBeforeClusterItemRendered sur ma DefaultClusterRenderer sous-classe.
ma solution a été de créer une nouvelle instance de ma sous-classe DefaultClusterRenderer et d'appeler setRenderer sur le ClusterManager à nouveau. Cette balise toutes les icônes cachées et recrée tout.
C'est hacky, la force brute et fâcheusement inefficace, mais il fonctionne. C'était la seule approche que j'ai trouvé qui a travaillé depuis la bibliothèque ne semble pas avoir de prise en charge explicite.
Vous pouvez obtenir des marqueurs spécifiques qui correspondent à leurs articles cluster ou cluster et vice versa en O (1) en utilisant Defaultclusterrenderer's getMarker (), getCluster () et getClusterItem () (définissez votre propre renderer pour accéder à l'objet renderer).
Utilisez ces méthodes pour changer les marqueurs de vos articles chaque fois que vous avez besoin.
...
DefaultClusterRenderer mRenderer = ...
mClusterManager.setRenderer(mRenderer);
...
public void reloadMarker(ClusterItem item) {
mRenderer.getMarker(item).setIcon(YOUR_ICON);
}
cependant, je ne recommande pas de les sauvegarder ailleurs, puisque ces méthodes renvoient les objets de cache du rendeur.
mClusterManager.cluster();
n'a pas fonctionné pour moi
ce n':
if (mMap != null) {
CameraPosition currentCameraPosition = mMap.getCameraPosition();
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(currentCameraPosition));
}
cela a déclenché un appel onCameraChange, où je faisais déjà mClusterManager.clearItems ()... mClusterManager.addItem(..) - pour les objets à l'intérieur de la région visible... mClusterManager.cluster ()
le contexte pour moi était que les pins disparaissaient en retournant au fragment affichant la carte (- seulement sur certains appareils comme Nexus 7, où il n'y avait pas d'appel automatique à OnCameraChange)
j'ai eu exactement le même problème. Aucune des solutions proposées ne fonctionnait pour moi. J'ai fait une classe qui étend le DefaultClusterRenderer et ajoute la méthode publique updateClusterItem(ClusterItem clusterItem) qui va forcer le marqueur associé à ce ClusterItem à être re-rendu (fonctionne à la fois avec les articles de cluster et cluster).
import android.content.Context;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterItem;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.clustering.view.DefaultClusterRenderer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public abstract class CustomClusterRenderer<T extends ClusterItem>
extends DefaultClusterRenderer<T> {
private ClusterManager<T> mClusterManager;
private Map<T, Marker> mClusterMap = new HashMap<>();
public CustomClusterRenderer(Context context, GoogleMap map,
ClusterManager<T> clusterManager) {
super(context, map, clusterManager);
mClusterManager = clusterManager;
}
@Override
@CallSuper
protected void onClusterItemRendered(T clusterItem, Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
mClusterMap.remove(clusterItem);
cleanCache();
}
@Override
@CallSuper
protected void onClusterRendered(Cluster<T> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
for (T clusterItem : cluster.getItems()) {
mClusterMap.put(clusterItem, marker);
}
cleanCache();
}
public void updateClusterItem(T clusterItem) {
Marker marker = getMarker(clusterItem);
boolean isCluster = false;
if (marker == null) {
marker = mClusterMap.get(clusterItem);
isCluster = marker != null;
}
if (marker != null) {
MarkerOptions options = getMarkerOptionsFromMarker(marker);
if (isCluster) {
Cluster cluster = getCluster(marker);
onBeforeClusterRendered(cluster, options);
} else {
onBeforeClusterItemRendered(clusterItem, options);
}
loadMarkerWithMarkerOptions(marker, options);
}
}
private void cleanCache() {
ArrayList<T> deleteQueue = new ArrayList<>();
Collection<Marker> clusterMarkers = mClusterManager
.getClusterMarkerCollection().getMarkers();
for (T clusterItem : mClusterMap.keySet()) {
if (!clusterMarkers.contains(mClusterMap.get(clusterItem))) {
deleteQueue.add(clusterItem);
}
}
for (T clusterItem : deleteQueue) {
mClusterMap.remove(clusterItem);
}
deleteQueue.clear();
}
private MarkerOptions getMarkerOptionsFromMarker(@NonNull Marker marker) {
MarkerOptions options = new MarkerOptions();
options.alpha(marker.getAlpha());
options.draggable(marker.isDraggable());
options.flat(marker.isFlat());
options.position(marker.getPosition());
options.rotation(marker.getRotation());
options.title(marker.getTitle());
options.snippet(marker.getSnippet());
options.visible(marker.isVisible());
options.zIndex(marker.getZIndex());
return options;
}
private void loadMarkerWithMarkerOptions(@NonNull Marker marker,
@NonNull MarkerOptions options) {
marker.setAlpha(options.getAlpha());
marker.setDraggable(options.isDraggable());
marker.setFlat(options.isFlat());
marker.setPosition(options.getPosition());
marker.setRotation(options.getRotation());
marker.setTitle(options.getTitle());
marker.setSnippet(options.getSnippet());
marker.setVisible(options.isVisible());
marker.setZIndex(options.getZIndex());
marker.setIcon(options.getIcon());
marker.setAnchor(options.getAnchorU(), options.getAnchorV());
marker.setInfoWindowAnchor(options.getInfoWindowAnchorU(), options.getInfoWindowAnchorV());
}
}
ma solution avec un CustomRenderer qui étend DefaultClusterRenderer
protected void onClusterItemRendered(T clusterItem, Marker marker) {
marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
}