You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:06:28