我正在使用 Google Maps V2 for Android 以及用于标记聚类的地图实用程序扩展库。应用程序的某些部分不需要获取聚类标记。
有没有办法禁止 clusterManager 对标记进行聚类,并在某些条件下让它再次聚类?
我找到了另一个解决方案。我发现在
DefaultClusterRenderer
方法上,shouldRenderAsCluster
负责标记是否将呈现为群集。所以我创建了一个 CustomRenderer 类,它扩展了 DefaultClusterRenderer
并创建了一个带有布尔变量的方法来确定渲染器是否应该集群。
public class CustomRenderer extends DefaultClusterRenderer<MarkerItem>
{
private boolean shouldCluster = true;
private static final int MIN_CLUSTER_SIZE = 1;
//Some code....
public void setMarkersToCluster(boolean toCluster)
{
this.shouldCluster = toCluster;
}
我在这里也覆盖了我之前提到的方法。
@Override
protected boolean shouldRenderAsCluster(Cluster<MarkerItem> cluster)
{
if (shouldCluster)
{
return cluster.getSize() > MIN_CLUSTER_SIZE;
}
else
{
return shouldCluster;
}
}
现在如果我想停止集群,我只需从我想要的活动中调用这个方法。
ClusterManager clusterManager = new ClusterManager<MarkerItem>(this, googleMap);
CustomRenderer customRenderer = new CustomRenderer(this, googleMap, clusterManager);
clusterManager.setRenderer(customRenderer);
customRenderer.setMarkersToCluster(false);
集群管理器实现只能执行内置的集群功能。如果您希望某些标记不聚集,则需要将这些标记直接添加到地图中。当您决定对这些标记进行聚类时,您需要将它们从地图中删除并将它们的信息传输给聚类管理器以供其接管。
在调用 setMarkersToCluster(false) 以禁用集群后需要一段时间,然后调用 CustomRenderer 的 shouldRenderAsCluster(Cluster cluster)。所以如果禁用集群后直接调用renderer.getMarker(markerItem)返回null。 等待一段时间:
new Handler(Looper.getMainLooper()).postDelayed(new Runnable(){
public void run(){
Marker marker=renderer.getMarker(markerItem);
}
}, 700L);
返回一个标记 !=null.
这不是一个理想的解决方案,因为等待时间可能并不总是有效。另一种方法是实现一个事件监听器和一个事件发布器(访问Java。实现监听器的正确模式) 活动制作于
@Override
protected boolean shouldRenderAsCluster(Cluster<MarkerItem> cluster) { ...}
并发送给事件生产者注册的观察者。
@Override
protected boolean shouldRenderAsCluster(Cluster<MarkerItem> cluster) {
//start clustering if at least 5 items overlap and mShouldCluster==true
int clusterSize = cluster.getSize();
boolean clusteringOn=(mShouldCluster && (clusterSize > 4));
notifyObserver(clusteringOn);
final String msg = "shouldRenderAsCluster; act. cluster size= = " + cluster.getSize() + ". should cluster? " + clusteringOn;
if (BuildConfig.DEBUG) {
Log.i(LOG_TAG, "+++" + msg);
}
return clusteringOn;
}
/**
* Renderer Settings
* @param shouldRender =true: rendering enabled; =false: rendering disabled
*/
public void setShouldRender(boolean shouldRender) {
mShouldCluster = shouldRender;
}
/**
* Register the observer at the event handler
* @param observer event listener of the observer
*/
public void setShouldRenderListener(IOnShouldRendererListener observer) {
mObserver=observer;
}
/**
* Notify the observer, if the observer ist registered at the event handler,
* @param shouldRender =true; rendering enabled; =false: rendering disabled
*/
private void notifyObserver(boolean shouldRender) {
// Notify the observer
if (mObserver!=null) {
mObserver.onShouldClusterCalled(shouldRender);
}
}
观察者类MarkerCollection2中实现的事件监听器实现了IOnShouldRendererListener。
public interface IOnShouldRendererListener {
void onShouldClusterCalled(boolean shouldRender);
}
public void onShouldClusterCalled(boolean shouldCluster) {
Log.i(LOG_TAG,"onShouldClusterCalled; should Cluster= " + shouldCluster);
if (!shouldCluster){
final MarkerItem markerItem = mMarkerList.get(mLastSelectedMarker);
final Marker marker = mClusterRenderer.getMarker(markerItem);
Log.i(LOG_TAG,"onShouldClusterCalled; marker!=null? " + (marker!=null));
if (marker!=null) {
mClusterRenderer.setShouldRender(true);
mClusterRenderer.setShouldRenderListener(null);
mMyInfoWindowAdapter.setClickedMarkerItem(markerItem);
LatLng position = markerItem.getPosition();
final CameraUpdate update;
if (markerItem instanceof RouteMarkerItem) {
//marker is a non clustered route marker: nothing to zoom
update = CameraUpdateFactory.newLatLng(position);
} else {
// marker is a clustered station marker; zoom to MinZoomLevelNotClustered
update = CameraUpdateFactory.newLatLngZoom(position, MIN_ZOOM_NOT_CLUSTERED);
}
//showInfoWindow, must run on UI thread
final Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
marker.showInfoWindow();
mMap.moveCamera(update);
}
});
}
}
}
启动 showInfoWindow 由以下人员完成:
mClusterRenderer.setShouldRenderListener(this);
mClusterRenderer.setShouldRender(false);
mClusterManager.cluster();
当调用 onShouldClusterCalled 时,侦听器设置为 null 以防止进一步通知并再次启用渲染。 这行得通,但这是一个过于复杂的解决方案,仅适用于打开信息窗口。所以我将继续使用地图扩展库: android-maps-extension
这个库对标记进行聚类,可以访问 GoogleMap 标记并调用 marker.showInfoWindow() 。T