I'm currently using GoogleMap in Flutter. I also use the clustering_google_maps package to display clusters of markers. The default behavior of this plugin is that every camera movement triggers an update of all the markers and clusters. This behavior takes into account the user zoom in/out and translation.

I added a feature where the camera moves according to the user's location whith the location package.

  initPlatformState() async {
    // Wait for the Completer to complete and return the GoogleMap Controler
    mapController = await _controller.future;
    // Set controller for the ClusteringHelper
    clusteringHelper.mapController = mapController;

    // Get database and update markers
    clusteringHelper.database = await DBHelper().database;
    clusteringHelper.updateMap();

    // Set parameters for location Service
    await _locationService.changeSettings(
        accuracy: LocationAccuracy.HIGH, interval: 1000);

    try {
      bool serviceStatus = await _locationService.serviceEnabled();
      print("Service status: $serviceStatus");
      if (serviceStatus) {
        _permission = await _locationService.requestPermission();
        print("Permission: $_permission");

        // If permission granted, get current location and subscribe to updates
        if (_permission) {
          LocationData location = await _locationService.getLocation();

          final myLocationMarkerId = MarkerId("myLocationMarker");
          myLocationMarker = Marker(
              markerId: myLocationMarkerId,
              position: LatLng(location.latitude, location.longitude),
              icon: BitmapDescriptor.defaultMarker,
              infoWindow: InfoWindow(
                  title: "My Location",
                  snippet: "Latitude: " +
                      location.latitude.toString() +
                      " Longitude: " +
                      location.longitude.toString()),
              );

          _locationSubscription = _locationService
              .onLocationChanged()
              .listen((LocationData result) async {
            if (cameraUpdateToMyLocation) {

              _currentCameraPosition = CameraPosition(
                  target: LatLng(result.latitude, result.longitude), zoom: 16);

              // Safety check if mapController not null
              if (mapController != null) {
                mapController.animateCamera(
                    CameraUpdate.newCameraPosition(_currentCameraPosition));
              }
            }

            if (mounted) {
              setState(() {
                _currentLocation = result;
                myLocationMarker = myLocationMarker.copyWith(
                    positionParam: LatLng(
                        _currentLocation.latitude, _currentLocation.longitude),
                infoWindowParam: InfoWindow(
                    title: "My Location",
                    snippet: "Latitude: " +
                        location.latitude.toString() +
                        " Longitude: " +
                        location.longitude.toString())
                        );

              });
            }
          });
        }
      } else {
        bool serviceStatusResult = await _locationService.requestService();
        print("Service status activated after request: $serviceStatusResult");
        if (serviceStatusResult) {
          initPlatformState();
        }
      }
    } on PlatformException catch (e) {
      print(e);
      if (e.code == 'PERMISSION_DENIED') {
        error = e.message;
      } else if (e.code == 'SERVICE_STATUS_ERROR') {
        error = e.message;
      }
    }
  }

I would like that this location update stops when the user moves the maps on the screen.

Unfortunately, the callback onCameraMove is triggered when the user move the map AND when the camera animation is launched.

Is it possible to trigger the inCameraMove callback, only when the user move the map ?

Thx !

EDIT It appears that onCameraMove is called in loop when I drag the map with my finger...


Solution 1: alexandreohara

It's not possible to differentiate the onCameraMove callback as far as I know. What are you trying to accomplish here? Can you change the plugin to display the clusters onCameraIdle callback? Would this solve your problem?


Solution 2: homayoun.azr

unfortunately, the google maps flutter does not support this feature for now. you can handle it by wrapping a map in the listener and control a boolean that shows what kind of action makes the camera move. for example, I want to find out if the camera moves by click on the markers (calling on tap callback of marker moves the camera) or the user manually drags the map. every time the user touches the map I change the "dragsTheScreen" boolean to true, and in on tap function of markers I change it to false which shows the camera movement is because of markers. so you can do it for any feature you want. for example, you want to find out if the camera movement is because of calling your own Special function or the user dragging: listener changes the boolean("dragsTheScreen") to true, and that function setState it to false.

                    Listener(
                  onPointerDown: (PointerDownEvent event){
                    setState(() {
                      dragsTheScreen=false;
                    });
                  },
                  child: GoogleMap(
                    markers: markerItemsForShow.toSet(),
                    mapType: MapType.normal,
                    onMapCreated: onMapCreated,
                    onCameraMove: onCameraMove,
                    onCameraIdle: onCameraIdle,
                 initialCameraPosition:CameraPosition(tilt:25,target:LatLng(32.71,51.66), zoom: 5),
                  ),
                ),

and in markers on tap callback when I am create them:

markerItemsForShow.add(Marker(
        markerId:...,
        position:...,
      onTap: (){
        setState(() {
          dragsTheScreen=true;
        });
      }
    ));