flutterdartgoogle-maps-markersfluttermap

FlutterMap - sticky marker not moving with map


I need to create location picker with sticky marker on map center. Marker position should be always at map center and marker pin should indicate current latlng position on any map move/zoom/scroll.

Does anybody know how to do that with FlutterMap?


Solution

  • You can just keep track of the map's center using the MapController to have the correct position for your marker.

    Code

    This is an example I've made with the picker being inside a dialog:

    class MapPickerDialog extends StatefulWidget {
      const MapPickerDialog({
        super.key,
        required this.initialLocation,
        this.initialZoom = 5,
        this.mapSize = const Size(300, 300),
      });
    
      /// Initial location of the map widget.
      final LatLng initialLocation;
    
      /// Initial zoom level of the map widget.
      ///
      /// Defaults to 5.
      final double initialZoom;
    
      /// Customize the size of the map widget.
      ///
      /// Defaults to 300x300.
      final Size mapSize;
    
      @override
      State<MapPickerDialog> createState() => _MapPickerDialogState();
    }
    
    class _MapPickerDialogState extends State<MapPickerDialog> {
      final mapController = MapController();
    
      late final pickedLocation = ValueNotifier<LatLng>(widget.initialLocation);
    
      @override
      void dispose() {
        pickedLocation.dispose();
        mapController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AlertDialog(
          title: const Text('Pick a location'),
          content: SizedBox.fromSize(
            size: widget.mapSize,
            child: FlutterMap(
              mapController: mapController,
              options: MapOptions(
                center: widget.initialLocation,
                zoom: widget.initialZoom,
                onMapReady: () => pickedLocation.value = mapController.center,
                onPositionChanged: (_, __) {
                  pickedLocation.value = mapController.camera.center;
                },
              ),
              children: [
                TileLayer(
                  urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                  tileProvider: NetworkTileProvider(),
                  userAgentPackageName: 'dev.fleaflet.flutter_map.example',
                ),
                ValueListenableBuilder<LatLng>(
                  valueListenable: pickedLocation,
                  builder: (context, location, _) {
                    return MarkerLayer(
                      markers: [
                        Marker(
                          point: location,
                          builder: (_) => const Icon(Icons.location_on),
                        ),
                      ],
                    );
                  },
                ),
              ],
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Cancel'),
            ),
            TextButton(
              onPressed: () => Navigator.pop(context, pickedLocation.value),
              child: const Text('OK'),
            ),
          ],
        );
      }
    }
    

    Screenshot

    enter image description here

    You can try the full example on zapp.run

    (Full disclosure, I'm one of the maintainers of the flutter_map repo)