5

我的 android 应用程序中有一个谷歌地图。它充满了标记,将标记聚集在一起……简而言之,这是一张完全可用的地图。

我想做的很简单。当用户点击 clusterItem 时,我想将图标更改为选定的图标。(简单地说,相同的标记但颜色不同)。

我如何在屏幕上使用大量标记,每次单击标记时都无法清理地图并添加标记。

所以:

mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
    @Override
    public boolean onClusterItemClick(MyItem myItem) {
        if (oldItemSelected != null) {
            mClusterManager.removeItem(oldItemSelected);
            oldItemSelected.setItemAsNotSelected();
            mClusterManager.addItem(oldItemSelected);
        }

        mClusterManager.removeItem(myItem);
        myItem.setItemAsSelected();
        mClusterManager.addItem(myItem);
        mClusterManager.cluster();

        oldItemSelected = myItem;
        return true;
    }
});

这个想法是从地图中删除单击的项目,将其设置为“选定”,添加新项目并使用 .cluster 方法刷新地图。

会发生什么:该项目没有改变,有时该项目是“重复的”并且所选内容位于“正常”项目的后面。

这就是我设置集群管理器的方式:

mClusterManager = new ClusterManager<MyItem>(this, map);
mClusterManager.setRenderer(new MyItemRenderer());
mClusterManager.setAlgorithm(new GridBasedAlgorithm<MyItem>());
map.setOnMarkerClickListener(mClusterManager);

这是项目渲染器:

private class MyItemRenderer extends DefaultClusterRenderer<MyItem> {
    public MyItemRenderer() {
        super(getApplicationContext(), map, mClusterManager);
    }

    @Override
    protected void onBeforeClusterItemRendered(MyItem myItem, MarkerOptions markerOptions) {
        markerOptions.title(myItem.getName());
        markerOptions.snippet(myItem.getAddress());
        markerOptions.icon(BitmapDescriptorFactory.fromResource(myItem.getIcon()));
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        return cluster.getSize() > 1;
    }

    public Marker getMarker(MyItem item) {
        return super.getMarker(item);
    }
}

有没有办法做到这一点而不必重新绘制地图中的每个项目?

public class MyItem extends DefaultClusterRenderer<WifiSpotItem> {

    private HashMap<Integer, Marker> markerWifiSpots = new HashMap<>();

    public MyItem(Context context, GoogleMap map, ClusterManager<WifiSpotItem> mClusterManager) {
        super(context, map, mClusterManager);
    }

    @Override
    protected void onBeforeClusterItemRendered(WifiSpotItem wifiSpotItem, MarkerOptions markerOptions) {

        if (markerOptions != null && wifiSpotItem != null) {
            markerOptions.title(wifiSpotItem.getName() != null ? wifiSpotItem.getName() : Constants.EMPTY_STRING);
            markerOptions.snippet(wifiSpotItem.getAddress() != null ? wifiSpotItem.getAddress() : Constants.EMPTY_STRING);
            markerOptions.icon(BitmapDescriptorFactory.fromResource(wifiSpotItem.getIcon()));
        }
    }

    @Override
    protected void onClusterItemRendered(WifiSpotItem clusterItem, Marker marker) {
        markerWifiSpots.put(clusterItem.getId(), marker);
        super.onClusterItemRendered(clusterItem, marker);
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        return cluster.getSize() > 4;
    }

    public Marker getMarker(WifiSpotItem item) {
        return super.getMarker(item);
    }

    public Marker getMarker(int id) {
        Marker item;
        if (markerWifiSpots != null) {
            item = markerWifiSpots.get(id);
        } else {
            item = null;
        }
        return item;
    }
}
4

1 回答 1

1

似乎渲染任务忽略了已经显示在屏幕上的对象。我尝试将MyItem对象的新实例(方法参数的副本onClusterItemClick)添加到集群管理器并且它可以工作。

mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
    @Override
    public boolean onClusterItemClick(MyItem myItem) {
        ...
        mClusterManager.removeItem(myItem);
        MyItem copy = myItem.copy();
        copy.setItemAsSelected();
        mClusterManager.addItem(copy);
        mClusterManager.cluster();
        ...
    }
});
于 2017-11-27T16:40:12.417 回答