Android 谷歌地图实用程序:如何从ClusterManager获取所有标记<>;?
对不起,我的英语不好 我尝试了Android 谷歌地图实用程序:如何从ClusterManager获取所有标记<>;?,android,google-maps-android-api-2,marker,markerclusterer,Android,Google Maps Android Api 2,Marker,Markerclusterer,对不起,我的英语不好 我尝试了ClusterManager.getMarkerCollection().getMarkers()方法,但它返回空集合 我在我的应用程序中使用谷歌地图实用程序库。每次屏幕旋转后,我都会创建AsynkTask,并在后台线程中从数据库读取数据,并将项目添加到ClusterManager: cursor.moveToFirst(); while (!cursor.isAfterLast()) { SomeData row = readSomeDataRow(cur
ClusterManager.getMarkerCollection().getMarkers()
方法,但它返回空集合
我在我的应用程序中使用谷歌地图实用程序库
。每次屏幕旋转后,我都会创建AsynkTask
,并在后台线程中从数据库读取数据,并将项目添加到ClusterManager
:
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
SomeData row = readSomeDataRow(cursor);
clusterManager.addItem(new ClusterItemImpl(row));
cursor.moveToNext();
}
clusterManager.cluster();
// cluster manager returns empty collection \|/
markers = clusterManager.getMarkerCollection().getMarkers();
当AsyncTask
完成其工作(即在主线程中)时,我尝试从ClusterManager
获取所有标记:
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
SomeData row = readSomeDataRow(cursor);
clusterManager.addItem(new ClusterItemImpl(row));
cursor.moveToNext();
}
clusterManager.cluster();
// cluster manager returns empty collection \|/
markers = clusterManager.getMarkerCollection().getMarkers();
但是ClusterManager
返回空集合
可能是在我调用
getMarkers()
ClusterManager的时候,但没有在地图上放置标记,稍后会执行(可能在后台线程中)。如果是这样的话,那么我怎样才能抓住那一刻呢?我在获取所有标记或至少获取标记的数量时遇到了同样的问题。我想我找到了找到标记的方法
我试着像你一样
markers = clusterManager.getMarkerCollection().getMarkers();
试试看
markers = clusterManager.getClusterMarkerCollection().getMarkers();
此行返回了标记,但我不确定这是否是您/我们想要的结果。我需要检查一下
注意
我会将我的答案作为评论来写,但我没有足够的观点。覆盖其中一个:
onBeforeClusterItemRendered
onBeforeClusterRendered
无群集的
OnClusterItem
就像
@Override
protected void onClusterRendered(Cluster<MyItem> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
}
@覆盖
受保护的void onClusterRendered(群集、标记){
super.onClusterRendered(集群、标记);
}
getItems()将返回集群中的标记我将为您提供一个很好的解决方法。首先,我将介绍一些背景。然后,我将告诉您修改代码的非常简单的方法 背景:让我们首先从库代码中了解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());
...
}
Collection<ClusterItemImpl> items = clusterManagerAlgorithm.getItems();
mAlgorithm被实例化为包含非HierarchicalDistanceBaseDalGorithm的PreachingGalGorithmDecorator。不幸的是,由于mAlgorithm被声明为私有,我们无法访问添加到算法中的项。然而,令人高兴的是,有一个简单的解决办法!我们只是使用ClusterManager.setAlgorithm实例化mAlgorithm。这允许我们访问算法类
变通方法:这是插入了变通方法的代码
private Algorithm<Post> clusterManagerAlgorithm;
public ClusterManager(Context context, GoogleMap map, MarkerManager markerManager) {
...
this.mAlgorithm = new PreCachingAlgorithmDecorator(new NonHierarchicalDistanceBasedAlgorithm());
...
}
Collection<ClusterItemImpl> items = clusterManagerAlgorithm.getItems();
Collection items=clusterManagerAlgorithm.getItems();
这将返回项目而不是标记对象,但我相信这是您所需要的。@Ethan solution有效。另一种方法是使用
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();
}
试试看{
Field Field=mClusterManager.getClass().getDeclaredField(“mAlgorithm”);
字段。setAccessible(true);
对象mAlgorithm=field.get(mClusterManager);
列表标记=新的ArrayList(((算法)mAlgorithm.getItems());
}捕获(无此字段例外){
e、 printStackTrace();
}捕获(非法访问例外e){
e、 printStackTrace();
}
注意:-将来如果字段名有任何更改(即
私有算法mAlgorithm
),则需要在业务逻辑中进行更改。Ethan的回答很好,但您仍然无法使用它获取标记。
您需要创建自定义ClusterRenderer并使用它来获取标记或ClusterItem
override fun onMapReady(map: GoogleMap) {
clusterManager = ClusterManager(this, map)
clusterRenderer = CustomClusterRenderer(this@ATMActivity, map, this)
clusterManager.renderer = clusterRenderer
}
inner class CustomClusterRenderer(
context: Context,
map: GoogleMap,
clusterManager: ClusterManager<CustomClusterItem>
) : DefaultClusterRenderer<CustomClusterItem>(context, map, clusterManager)
它并没有为您提供完整的标记集合,但如果您确实仍然需要它,您应该使用loop来创建它。您应该尝试以下方法:
private MyItem mitemfilter;
renderer = new MyClusterManagerRender(this, googleMap, clusterManager);
clusterManager.setRenderer(renderer);
addItems();
private void addItems() {
clusterManager.addItem(mitemfilter=new MyItem (19.641936, -99.132669, "food", "Villa Esmeralda, 54910 Fuentes del Valle, Méx.",R.drawable.ic_camaron));
}
private void foodfilter(){
renderer.getMarker(mitemfilter).setVisible(false);
}
A确认您的模型Myitem已定义。
这对于我尝试在集群内实现过滤非常有用。您找到解决问题的方法了吗?clusterManager.getClusterMarkerCollection().getMarkers();仅当标记处于缩放级别时才返回标记,以便我们可以在地图中看到它们。由于ClusterManager方法cluster()创建并调用ClusterManager.ClusterTask()AsyncTask,因此在调用cluster()后尝试正确获取标记是错误的。似乎当ClusterManager.ClusterTask完成时,它会调用ClusterRenderer对象.ClusterManager.getClusterMarkerCollection().getMarkers()上的方法OnClusterChanged();仅当标记处于缩放级别时才返回标记,以便我们可以在地图中看到它们是的,您是对的,我发现它只返回出现的标记,而不返回clustersGreat解决方案中的标记!您有一个输入错误:应该是'clusterManagerAlgorithm=new Non-HierarchicalDistanceBasedAlgorithm'(您缺少Non-HierarchicalDistanceBasedAlgorithm中的第一个'N'),只是说-原始的setAlgorithm方法不可避免地用缓存算法包装您的算法,在某些情况下,这可能会很困难,因为这种包装算法也会自动为较低和较高的缩放级别获取集群,这意味着一个getClusters(zoom)调用=3个调用。我知道它们是线程化的,但是在同样的情况下,仅仅说这可能是不需要的。这个解决方案对meThis非常好,这是到目前为止唯一对我有效的方法,但是它并没有返回所有标记。然而,一个简单的循环可以满足OP的要求。干杯