Android中如何在InfoWindowClickListener内获取ClusterItem?
Android Google Maps聚合点InfoWindow点击获取自定义标签
问题描述
在Android应用中集成Google Maps并实现点聚合功能后,自定义了MyClusterItem类存储点位信息与标签数组types:
public class MyClusterItem implements ClusterItem { private final LatLng position; public final Integer vectorId; public List<String> types; public MyClusterItem(double lat, double lng, List<String> types, int vectorId) { position = new LatLng(lat, lng); this.types = types; this.vectorId = vectorId; } // 重写ClusterItem接口方法 @Override public LatLng getPosition() { return position; } public List<String> getTagCluster(){ return types;} }
创建聚合项时传入标签数组:
MyClusterItem newItem = new MyClusterItem(pointLoc.latitude, pointLoc.longitude, pointObj.types, vectorId); clusterManager.addItem(newItem);
配置自定义InfoWindowAdapter和点击监听后,无法在OnInfoWindowClickListener中直接获取MyClusterItem的types标签:
map.setInfoWindowAdapter(new CustomInfoWindowAdapter(getContext(), map)); map.setOnInfoWindowClickListener(marker -> { // 需要在此处获取types标签 });
自定义渲染器代码如下:
private class CustomClusterItemRenderer extends DefaultClusterRenderer<MyClusterItem> { public CustomClusterItemRenderer(Context context, GoogleMap map, ClusterManager<MyClusterItem> clusterManager) { super(context, map, clusterManager); } @Override protected void onBeforeClusterItemRendered(@NonNull MyClusterItem clusterItem, MarkerOptions markerOptions) { markerOptions.icon(bitmapDescriptorFromVector(getContext(), clusterItem.vectorId)) .title(clusterItem.getTitle()); } private BitmapDescriptor bitmapDescriptorFromVector(Context context, int vectorResId) { // 矢量图转BitmapDescriptor的实现代码 return BitmapDescriptorFactory.fromBitmap(bitmap); } }
解决方案
方法一:通过ClusterManager反向获取MyClusterItem
ClusterManager提供了getClusterItem(Marker marker)方法,可直接通过点击的Marker获取绑定的MyClusterItem,进而拿到标签:
map.setOnInfoWindowClickListener(marker -> { MyClusterItem clusterItem = clusterManager.getClusterItem(marker); if (clusterItem != null) { List<String> types = clusterItem.types; // 此处可使用types标签进行后续逻辑处理 } });
方法二:为Marker设置Tag绑定MyClusterItem
若方法一在特殊场景下不生效,可在自定义渲染器中重写onClusterItemRendered方法,将MyClusterItem设置为Marker的Tag:
private class CustomClusterItemRenderer extends DefaultClusterRenderer<MyClusterItem> { public CustomClusterItemRenderer(Context context, GoogleMap map, ClusterManager<MyClusterItem> clusterManager) { super(context, map, clusterManager); } @Override protected void onBeforeClusterItemRendered(@NonNull MyClusterItem clusterItem, MarkerOptions markerOptions) { markerOptions.icon(bitmapDescriptorFromVector(getContext(), clusterItem.vectorId)) .title(clusterItem.getTitle()); } // 新增方法:给渲染完成的Marker绑定MyClusterItem作为Tag @Override protected void onClusterItemRendered(@NonNull MyClusterItem clusterItem, @NonNull Marker marker) { super.onClusterItemRendered(clusterItem, marker); marker.setTag(clusterItem); } private BitmapDescriptor bitmapDescriptorFromVector(Context context, int vectorResId) { // 矢量图转BitmapDescriptor的实现代码 return BitmapDescriptorFactory.fromBitmap(bitmap); } }
随后在点击监听中通过Tag获取MyClusterItem:
map.setOnInfoWindowClickListener(marker -> { Object tag = marker.getTag(); if (tag instanceof MyClusterItem) { MyClusterItem clusterItem = (MyClusterItem) tag; List<String> types = clusterItem.types; // 此处可使用types标签进行后续逻辑处理 } });
注意:如果点击的是聚合集群(多个点位合并的Marker),
getClusterItem会返回null,此时需要判断Marker是否为集群标识,再做对应处理(例如获取集群内所有Item的标签)。
内容的提问来源于stack exchange,提问作者maxet24
相关产品推荐
相关产品推荐

