Google Maps Utility:如何从ClusterManager获取所有标记<?>?

对不起我的英语不好

我尝试了ClusterManager<?>.getMarkerCollection().getMarkers()方法,但它返回空集合。

我在我的应用程序Google Maps Utility Library 。 每次屏幕旋转后,我创buildAsynkTask并在后台线程从数据库读取数据,并添加项目到ClusterManager

 cursor.moveToFirst(); while (!cursor.isAfterLast()) { SomeData row = readSomeDataRow(cursor); clusterManager.addItem(new ClusterItemImpl(row)); cursor.moveToNext(); } 

AsyncTask完成其工作(即在主线程中)时,我尝试从ClusterManager获取所有标记

 clusterManager.cluster(); // cluster manager returns empty collection \|/ markers = clusterManager.getMarkerCollection().getMarkers(); 

但是ClusterManager返回空集合。

可能在我调用getMarkers()的那一刻, ClusterManager却没有在地图上放置标记,稍后会做(可能在后台线程中)。 如果是这样的话,那我该怎么抓住那一刻呢?

Solutions Collecting From Web of "Google Maps Utility:如何从ClusterManager获取所有标记<?>?"

我会给你一个很好的解决方法。 首先,我会给出一些背景。 然后,我会告诉你修改你的代码的非常简单的方法。

背景:首先来看一下库代码中ClusterManager.addItem的实现:

 public void addItem(T myItem) { this.mAlgorithmLock.writeLock().lock(); try { this.mAlgorithm.addItem(myItem); } finally { this.mAlgorithmLock.writeLock().unlock(); } } 

正如你所看到的,当你调用clusterManager.addItem时,ClusterManager会调用this.mAlgorithm.addItem。 mAlgorithm是您的项目存储的地方。 现在我们来看看ClusterManager的默认构造函数:

 public ClusterManager(Context context, GoogleMap map, MarkerManager markerManager) { ... this.mAlgorithm = new PreCachingAlgorithmDecorator(new NonHierarchicalDistanceBasedAlgorithm()); ... } 

mAlgorithm被实例化为包含NonHierarchicalDistanceBasedAlgorithm的PreCachingAlgorithmDecorator。 不幸的是,由于mAlgorithm被声明为private,因此我们无法访问正在添加到algorithm中的项目。 然而,幸运的是一个简单的解决方法! 我们只是使用ClusterManager.setAlgorithm实例化mAlgorithm。 这允许我们访问algorithm类。

解决方法:这是您的代码与插入的解决方法。

  1. 把这个声明和你的类variables放在一起:

     private Algorithm<Post> clusterManagerAlgorithm; 
  2. 在你实例化你的ClusterManager的地方,立即放置这个:

      // Instantiate the cluster manager algorithm as is done in the ClusterManager clusterManagerAlgorithm = new NonHierarchicalDistanceBasedAlgorithm(); // Set this local algorithm in clusterManager clusterManager.setAlgorithm(clusterManagerAlgorithm); 
  3. 您可以将代码插入群集中的项目完全相同。

  4. 当你想访问插入的项目时,只需使用algorithm而不是ClusterManager:

     Collection<ClusterItemImpl> items = clusterManagerAlgorithm.getItems(); 

这将返回项目而不是标记对象,但我相信这是你所需要的。

重写其中之一:

onBeforeClusterItemRendered

onBeforeClusterRendered

onClusterRendered

onClusterItemRendered

就像

  @Override protected void onClusterRendered(Cluster<MyItem> cluster, Marker marker) { super.onClusterRendered(cluster, marker); } 

cluster.getItems()将返回集群中的标记

我有同样的问题得到所有的标记或至less得到标记的数量。 我想我find了获得标记的解决scheme。

我试着像你一样

 markers = clusterManager.getMarkerCollection().getMarkers(); 

改为尝试

 markers = clusterManager.getClusterMarkerCollection().getMarkers(); 

这条线返回了我的标记,但我不知道这是否是你/我们想要的结果。 我需要检查这个。

注意我会写我的答案作为评论,但我没有足够的观点..

@解决scheme的作品。 另一个mAlgorithm是使用Reflection API来访问ClusterManager类的mAlgorithm (正如Ethan提供的mAlgorithm是你的项存储的地方)字段。

 try { Field field = mClusterManager.getClass().getDeclaredField("mAlgorithm"); field.setAccessible(true); Object mAlgorithm = field.get(mClusterManager); List<MapItems> markers = new ArrayList<>(((Algorithm<MapItems>)mAlgorithm).getItems()); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } 

注意: – 将来如果字段名称有任何变化(即private Algorithm<T> mAlgorithm ),则需要在业务逻辑中进行更改。