Введение
Понадобилась мне как-то карта во флаттер-приложении. Гугл и Яндекс карты использовать не хотелось и оставалось только воспользоваться OSM. Карту сделать довольно просто, но и понадобилось добавить всплывающее окно при нажатии на маркер положения на карте. Перед тем как писать что-то самостоятельно решил поискать уже готовые решения и нашел плагин flutter_map_marker_popup.
Смотрим плагин
Зависимости которые потребуются:
dependencies: flutter: sdk: flutter flutter_map: any latlong2: any flutter_map_marker_popup: any
Для начала добавим карту Flutter_map. Из важного тут — urlTemplate, который указывает на сервер OSM. Настройки в MapOptions передадим извне.
class MapPage extends StatefulWidget { MapPage({super.key, required this.center, double? zoom}){ this.zoom = zoom ?? 9.0; } final LatLng center; late final double zoom; @override State<MapPage> createState() => _MapPageState(); } class _MapPageState extends State<MapPage> { final urlTemplate = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Map page"), ), body: FlutterMap( mapController: MapController(), options: MapOptions( center: widget.center, zoom: widget.zoom, ), children: [ TileLayer( urlTemplate: urlTemplate, ), ], ), ); } }
Дальше будем, например по долгому нажатию, создавать маркер на карте. Напишем функцию которая будет добавлять новый маркер в массив маркеров и передадим ее в MapOptions onLongPress: addMarker.
final List<Marker> _markers = []; addMarker(tapPosition, point){ _markers.add(Marker( point: point, builder: (c) => const Icon(Icons.location_on, size: 40), width: 40, height: 40,)); }
Теперь эти маркеры можно стандартно отобразить с помощью слоя MarkerLayer(markers: _markers), но тогда не получится отслеживать нажатие по ним и отображать что-либо. Для этих задач в плагине flutter_map_marker_popup есть PopupMarkerLayerWidget. Добавляем этот слой:
PopupMarkerLayerWidget( options: PopupMarkerLayerOptions( popupController: _popupLayerController, markers: _markers, markerRotateAlignment: PopupMarkerLayerOptions.rotationAlignmentFor(AnchorAlign.top), popupBuilder: (BuildContext context, Marker marker) => ExamplePopup(marker), ), ),
В этот слой передаются маркеры, контроллер, и способ создания попапа. ExamplePopup — это виджет который будет появляться при нажатии на маркер. В нем и будут правила отображения всплывающего окна.
class ExamplePopup extends StatefulWidget { final Marker marker; const ExamplePopup(this.marker, {Key? key}) : super(key: key); @override State<StatefulWidget> createState() => _ExamplePopupState(); } class _ExamplePopupState extends State<ExamplePopup> { int _currentIcon = 0; @override Widget build(BuildContext context) { return Card( child: InkWell( onTap: () => setState(() { _currentIcon = (_currentIcon + 1) % 4; }), child: Row( mainAxisSize: MainAxisSize.min, children: <Widget>[ Padding( padding: const EdgeInsets.only(left: 20, right: 10), child: Image.asset('assets/${_currentIcon+1}.png', width: 40, height: 40,), ), _cardDescription(context), ], ), ), ); } Widget _cardDescription(BuildContext context) { return Padding( padding: const EdgeInsets.all(10), child: Container( constraints: const BoxConstraints(minWidth: 100, maxWidth: 200), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: <Widget>[ const Text( 'Popup for a marker!', overflow: TextOverflow.fade, softWrap: false, style: TextStyle( fontWeight: FontWeight.w500, fontSize: 14.0, ), ), const Padding(padding: EdgeInsets.symmetric(vertical: 4.0)), Text( 'Position: ${widget.marker.point.latitude}, ${widget.marker.point.longitude}', style: const TextStyle(fontSize: 12.0), ), Text( 'Marker size: ${widget.marker.width}, ${widget.marker.height}', style: const TextStyle(fontSize: 12.0), ), ], ), ), ); } }
Примечание, для получения картинок из папки assets надо в pubspec.yml добавить настройку:
flutter: assets: - assets/
И вот у нас по нажатию на маркер всплывает окно с котиками.

Всем спасибо! Если интересно, есть телеграмм, заходите присаживайтесь).
ссылка на оригинал статьи https://habr.com/ru/post/689578/
Добавить комментарий