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?
You can just keep track of the map's center using the MapController
to have the correct position for your marker.
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'),
),
],
);
}
}
You can try the full example on zapp.run
(Full disclosure, I'm one of the maintainers of the flutter_map repo)