Попап на флаттер карте 또는 flutter_map_marker_popup

5783 단어 mapflutterosm

베데니에



Понадобилась мне как-то карта во флаттер-приложении. Гугл и яндекс карты использовать не хотелось и оставалось только воспользоваться OSM. Ну и понадобилось добавить всплывающее окно при нажатии на маркер положения на карте, нашел как это делать для гугла и яндекса, а для flutter_mup не сразу нашел. flutter_map_marker_popup에 등록된 항목이 없습니다.

스모트림 플라긴



Зависимости укажем такие:

dependencies:
  flutter:
    sdk: flutter
  flutter_map: any
  latlong2: any
  flutter_map_marker_popup: any


Flutter_map에 대해 자세히 알아보십시오. Добавим ее

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,
          ),
        ],
      ),
    );
  }
}


Дальше давайте как-то добавлять маркеры на карту и отобразим их стандартным образом. Добавим лист MARKеров, и Функцию добавить MARKер. В 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,));
  }


Теперь эти MARKеры можно стандартно отобразить с помощью слоя MarkerLayer(markers: _markers,) , но тогда не получится отслеживать нажатие по анимри отжь. flutter_map_marker_popup 에 등록된 항목PopupMarkerLayerWidget . Добавляем этот SLой

PopupMarkerLayerWidget(
            options: PopupMarkerLayerOptions(
              popupController: _popupLayerController,
              markers: _markers,
              markerRotateAlignment:
              PopupMarkerLayerOptions.rotationAlignmentFor(AnchorAlign.top),
              popupBuilder: (BuildContext context, Marker marker) =>
                  ExamplePopup(marker),
            ),
          ),


Ага, мы передаем туда все MARKеры и что-то с ними делаем. Что такое 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/


И вот раз, и у нас по нажатию на MARKER всплывает окно с котиками.



Всем спасибо! Если интересно, есть телеграмм , заходите присаживайтесь).

좋은 웹페이지 즐겨찾기