Android cluster and marker clicks

前端 未结 4 2000
执笔经年
执笔经年 2020-12-03 05:56

I\'m using the android clustering utility on a map and succesffuly implemented an onclick listener with mClusterManager.setOnClusterItemClickListener() for all the markers h

相关标签:
4条回答
  • 2020-12-03 06:08

    Simple solution

    Just got the same problem. The solution is simple: call ClusterManager listeners from your own event listeners. Look at the concept:

    private OnMapReadyCallback listenerMapReady = (googleMap) ->
    {
        googleMap.setOnCameraIdleListener(() -> {
            mClusterManager.onCameraIdle(); //call cluster manager listener
            //....your code for setOnCameraIdleListener event
        });
    
        googleMap.setOnMarkerClickListener(marker -> {
            if (marker != null && ... check if marker is NOT from cluster manager ....) {
                //......your code for unclustered markers, added directly to the map
                return false;
            }
            else
                return mClusterManager != null && mClusterManager.onMarkerClick(marker); // let cluster manager do his job
        });
    }
    

    To ensure that cluster manager internals will not intercept onMarkerClick listener, lets reset listener every time after cluster manager did his stuff. I've put it right into OnCameraIdle event:

    public class FragmentRoutes extends Fragment {
    
    private MapView mMapView;
    private GoogleMap mMap;
    
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_routes, container, false);
    
        mMapView = rootView.findViewById(R.id.ac_main_map); // map rendering holder
        if (mMapView != null)
            mMapView.onCreate(savedInstanceState);
        //....... other onCreate mess
    }
    
    
    @Override
    public void onResume() {
        super.onResume();
        if (mMapView != null) {
            mMapView.onResume();
            mMapView.getMapAsync(listenerMapReady);
        }
    }
    
    
    // on marker click listener for the map
    private GoogleMap.OnMarkerClickListener listenerMarkerClick = marker -> {
        //markers which tag is TransportItem were added directly to map, I will take care of them
        if (marker != null && marker.getTag() instanceof TransportItem) {
            //......do my tasks for clicked transport marker
            return false;
        }
        else {
           // other markers are cluster manager markers, process as usual
           return mClusterManager != null && mClusterManager.onMarkerClick(marker);
        }
    }
    
    // listener for map ready event
    private OnMapReadyCallback listenerMapReady = (googleMap) ->
    {
        if (getContext() == null)
            return;
    
        mMap = googleMap;
    
        mMap.setOnCameraIdleListener(() -> {
            mClusterManager.onCameraIdle();
    
            //....your code for setOnCameraIdleListener event
    
            // now reset marker click listener
            mMap.setOnMarkerClickListener(listenerMarkerClick); //reset marker click listener
        });
    }
    
    
    }
    

    Thats all! Happy androiding :)

    0 讨论(0)
  • 2020-12-03 06:09

    You can create a new MarkerManager that you pass into the ClusterManager constructor. Then make a new Marker collection using MarkerManager#newCollection and add your normal Markers to the map using the MarkerManager.Collection#addMarker method.

    Then, instead of calling mMap.setOnMarkerClickListener(mClusterManager), call mMap.setOnMarkerClickListener(mMarkerManager), and it will handle forwarding your Marker click events to the proper listeners. You'll also need to set up your onMarkerClick listener for normal Markers with the MarkerManager.Collection#setOnMarkerClickListener(GoogleMap.OnMarkerClickListener markerClickListener) function.

    I recommend looking over the source of the MarkerManager and ClusterManager classes to get a better idea of how the classes interact.

    0 讨论(0)
  • 2020-12-03 06:11

    Here you can see my code. The example is complete with all you need.

    public class HomeFragment extends Fragment implements OnMapReadyCallback, ClusterManager.OnClusterClickListener<MarkerClusterItem> {
    
        ...
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            // Add a marker in Sydney, Australia,
            this.googleMap = googleMap;
            this.googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
    
    
            setUpClusterManager();
    
            ...
        }
    
        private void setUpClusterManager(){
            // cluster
            clusterManager = new ClusterManager<MarkerClusterItem>(getActivity(), this.googleMap);
            clusterManager.setAnimation(false);
            MarkerClusterRenderer clusterRenderer = new MarkerClusterRenderer(getActivity(), googleMap, clusterManager);
            clusterManager.setRenderer(clusterRenderer);
            // marker clic
            clusterManager.setOnClusterClickListener(this);
        }
    
        @Override
        public boolean onClusterClick(Cluster<MarkerClusterItem> cluster) {
        if (cluster == null) return false;
            // do your stuff here 
            return true;
        }
    
    
     }
    
    0 讨论(0)
  • 2020-12-03 06:20

    One more way to receive the click event for Marker is using OnClusterItemClickListener interface.

    Call mClusterManager.setOnClusterItemClickListener(this); and make your class implement OnClusterItemClickListener

    Then inside the onClusterItemClick method, you will get the ClusterItem which is the marker that was clicked,

    @Override
    public boolean onClusterItemClick(ClusterItem clusterItem) {
    
        Toast.makeText(getActivity(), "Latitude " + clusterItem.getPosition().latitude, Toast.LENGTH_LONG).show();
    
        return true;
    }
    
    0 讨论(0)
提交回复
热议问题