用于 clusterItems 的 Android 谷歌地图 markerClickListener

Posted

技术标签:

【中文标题】用于 clusterItems 的 Android 谷歌地图 markerClickListener【英文标题】:Android Google maps markerClickListener for clusterItems 【发布时间】:2017-08-06 21:11:04 【问题描述】:

我正在尝试为我的 googlemaps 标记实现集群。目前,我有一些自定义标记颜色,当您单击它们时会触发 API 调用。加载这些结果后,将打开一个底页,其中包含该标记的特定信息。

我想保留相同的功能(自定义标记/clickListeners/标记周围的半径),但在缩小时添加集群。我查看了不同的资源来寻求帮助:

android cluster and marker clicks

Android marker-clustering

MarkerManager.java

但我不确定如何为集群项目实现自定义标记和侦听器。我能够在没有点击监听器的情况下获得带有标准标记的集群。以下是一些用于说明的图片:

这是我目前的情况(我想对这些标记进行聚类)。如您所见,当我单击标记时会弹出底部工作表

这是我目前能做的,但我想把它和上一张图结合起来

这是我的地图片段代码的重要部分,(Point 类确实实现了ClusterItem 接口):

private Map<Marker, Point> retailerInfo = new HashMap<>();

    private void markGeofencesOnMap() 
        new GeofenceAreasRequest().getAllAreas(new GeofenceAreasCallback() 
            @Override
            public void onAreasLoaded(List<Point> points) 
                for (final Point point : points) 
                    markerForGeofence(point);
                    drawRadius(point);
                
            
            @Override
            public void failedOnAreasLoaded(int message) 
                Snackbar.make(coordinatorLayout, R.string.failed_loading_areas, Snackbar.LENGTH_LONG).show();
            
        );
    

    private void markerForGeofence(Point point) 
        LatLng latLng = new LatLng(point.getLatitude(), point.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions()
                .position(latLng)
                .flat(true)
                .title(point.getTitle())
                .icon(BitmapDescriptorFactory.defaultMarker(195));
//        markerManager.getCollection("markerCollection").addMarker(markerOptions);
//        markerManager.getCollection("markerCollection").setOnMarkerClickListener(this);
//        mClusterManager.addItem(point);
        geoFenceMarker = googleMap.addMarker(markerOptions);
        retailerInfo.put(geoFenceMarker, point);
    

    private void drawRadius(Point point) 
        CircleOptions circleOptions = new CircleOptions()
                .center(geoFenceMarker.getPosition())
                .strokeColor(Color.argb(50, 70, 70, 70))
                .fillColor(Color.argb(100, 150, 150, 150))
                .radius(point.getRadius());
        googleMap.addCircle(circleOptions);
    

    private void googleMapSettings() 
        int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),
                Manifest.permission.ACCESS_FINE_LOCATION);
        if (permissionCheck == PackageManager.PERMISSION_GRANTED) 
            googleMap.setMyLocationEnabled(true);
         else 
            SystemRequirementsChecker.checkWithDefaultDialogs(getActivity());
        
        googleMap.getUiSettings().setZoomControlsEnabled(true);
        CameraPosition cameraPosition = new CameraPosition.Builder().target(getLastLocation()).zoom(12).build();
        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        googleMap.setOnMapClickListener(this);
//        markerManager = new MarkerManager(googleMap);
//        markerManager.newCollection("markerCollection");
//        mClusterManager = new ClusterManager<Point>(getActivity(), googleMap );//, markerManager);
//        googleMap.setOnMarkerClickListener(mClusterManager); //markerManager);
        googleMap.setOnCameraIdleListener(mClusterManager);
        googleMap.setOnMarkerClickListener(this);
    

    @Override
    public boolean onMarkerClick(Marker marker) 
        if (retailerInfo != null) 
            String retailerId = retailerInfo.get(marker).getRetailer();
            new RetailersRequest().getRetailer(retailerId, new RetailersCallback() 
                @Override
                public void onRetailersLoad(List<Retailer> retailers) 
                    for (final Retailer retailer : retailers) 
                        mMapRetailerName.setText(retailer.getName());
                        mMapRetailerStreet.setText(retailer.getStreet());
                        mMapRetailerHouseNr.setText(retailer.getHousenumber());
                        mMapRetailerPostalCode.setText(retailer.getPostalCode());
                        mMapRetailerCity.setText(retailer.getCity());
                    
                    bottomSheet.setVisibility(View.VISIBLE);
                    mBottomSheetBehavior.setPeekHeight(400);
                    mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                

                @Override
                public void failedOnRetailersLoaded(int code) 
                    Snackbar.make(coordinatorLayout, getString(R.string.failed_loading_retailers) + code, Snackbar.LENGTH_LONG).show();
                
            );
            CameraPosition cameraPosition = new CameraPosition.Builder().target(marker.getPosition()).zoom(14).build();
            googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        
        return true;
    

    @Override
    public void onMapClick(LatLng latLng) 
        bottomSheet.setVisibility(View.GONE);
    

    @Override
    public void onMapReady(GoogleMap googleMap) 
        this.googleMap = googleMap;
        googleMapSettings();
        markGeofencesOnMap();
    

我希望有人可以在正确的方向上帮助我。谢谢!

【问题讨论】:

【参考方案1】:

好的,经过更多的尝试和错误,我想我已经解决了大部分问题。我所要做的就是将自定义DefaultClusterRenderer 附加到我的集群管理器。在 mapfragment 中,我可以使用 onClusterItemClick 来处理标记点击。我仍然遇到的一个问题是,放大和缩小时,圆圈并没有全部正确渲染。

private void markGeofencesOnMap() 
    new GeofenceAreasRequest().getAllAreas(new GeofenceAreasCallback() 
        @Override
        public void onAreasLoaded(List<Point> points) 
            for (final Point point : points) 
                mClusterManager.addItem(point);
            
        
    );


private void googleMapSettings()         
    mClusterManager = new ClusterManager<Point>(getActivity(), googleMap );
    // attach custom renderer behaviour
    mClusterManager.setRenderer(new OwnPointRendered(getActivity().getApplicationContext(), googleMap, mClusterManager)); 
    mClusterManager.setOnClusterItemClickListener(this);
    googleMap.setOnMarkerClickListener(mClusterManager);
    googleMap.setOnCameraIdleListener(mClusterManager);


@Override
public boolean onClusterItemClick(ClusterItem clusterItem) 
    // cast ClusterItem to my Point class to handle marker clicks
    Point retailer = (Point) clusterItem;
    String retailerId = retailer.getRetailer();
    return true;

OwnPointRendered.class

public class OwnPointRendered extends DefaultClusterRenderer<Point> 
private final GoogleMap map;
private List<Circle> circleList = new ArrayList<>();

public OwnPointRendered(Context context, GoogleMap map,
                        ClusterManager<Point> clusterManager) 
    super(context, map, clusterManager);
    this.map = map;


@Override
protected void onBeforeClusterItemRendered(Point item, MarkerOptions markerOptions) 
    markerOptions.flat(true);
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(195));
    drawRadius(item);
    super.onBeforeClusterItemRendered(item, markerOptions);


@Override
protected void onClusterRendered(Cluster<Point> cluster, Marker marker) 
    super.onClusterRendered(cluster, marker);
    for (Circle circle : circleList) 
        circle.remove();
    
    circleList.clear();


private void drawRadius(Point point) 
    CircleOptions circleOptions = new CircleOptions()
            .center(point.getPosition())
            .strokeColor(Color.argb(50, 70, 70, 70))
            .fillColor(Color.argb(100, 150, 150, 150))
            .radius(point.getRadius());
    Circle circle = map.addCircle(circleOptions);
    circleList.add(circle);

【讨论】:

有没有人找到删除圈子的解决方案?

以上是关于用于 clusterItems 的 Android 谷歌地图 markerClickListener的主要内容,如果未能解决你的问题,请参考以下文章

在 android 谷歌地图中更改集群管理器项目图标

使用 Googles android-maps-utils 在最大缩放级别禁用集群

用于按钮的 Android 滑动抽屉

用于关联规则挖掘的android库是啥?

Android 蓝牙发现 API 不适用于 Android 6.0

用于调试 android TV 应用程序的 Android 盒子