Flutter使用Mapbox实现点击地图放置Marker的方案
Flutter + Mapbox 点击放置Marker 实现方案
以下实现基于官方维护的mapbox_maps_flutter稳定版封装,无第三方额外依赖,体验与原生渲染一致。
前置准备
- 在项目
pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter mapbox_maps_flutter: ^2.3.0
- 提前完成Mapbox Access Token基础配置:Android端在
AndroidManifest.xml配置token字段,iOS端在Info.plist添加对应配置,确保地图可正常加载。
核心实现逻辑
整个功能只需要3步即可跑通,不建议用Stack层叠组件覆盖地图的方式实现假Marker,会出现缩放不同步、性能差的问题,直接用Mapbox原生的点标注API实现即可:
- 地图初始化完成后创建点标注管理器,绑定地图点击事件
- 触发地图点击时,拿到点击位置的经纬度坐标
- 调用点标注管理器的添加方法,在对应坐标位置渲染Marker
可直接运行的核心代码
import 'package:flutter/material.dart'; import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; class MapMarkerPage extends StatefulWidget { const MapMarkerPage({super.key}); @override State<MapMarkerPage> createState() => _MapMarkerPageState(); } class _MapMarkerPageState extends State<MapMarkerPage> { late MapboxMap mapboxController; PointAnnotationManager? _annotationManager; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("点击放置Marker")), body: MapboxWidget( accessToken: "替换为你自己的Mapbox Access Token", onMapCreated: _onMapCreated, initialCameraOptions: CameraOptions( center: Point(coordinates: Position(116.3974, 39.9093)), zoom: 12, ), ), floatingActionButton: FloatingActionButton( child: const Icon(Icons.clear_all), onPressed: () async { // 清空所有已添加的Marker await _annotationManager?.deleteAll(); }, ), ); } void _onMapCreated(MapboxMap controller) async { mapboxController = controller; // 初始化点标注管理器 _annotationManager = await controller.annotations.createPointAnnotationManager(); // 监听地图点击事件 controller.onMapTap.add((event) { final clickPosition = Point( coordinates: Position(event.coordinate.lng, event.coordinate.lat), ); _addMarker(clickPosition); }); } Future<void> _addMarker(Point position) async { if (_annotationManager == null) return; // 添加Marker,可自定义图标、大小、偏移量等参数 await _annotationManager!.create( PointAnnotationOptions( geometry: position, iconImage: "mapbox-marker-icon-red", // 内置红色Marker图标,可替换为自定义图片 iconSize: 1.0, iconAnchor: IconAnchor.BOTTOM, // 图标锚点设为底部,精准对准点击坐标 ), ); } @override void dispose() { mapboxController.onMapTap.clear(); _annotationManager?.dispose(); super.dispose(); } }
自定义扩展说明
- 如果需要使用自定义图标作为Marker,提前调用
mapboxController.style.addStyleImage方法将本地资源图注册到地图样式,再把iconImage参数替换为注册时自定义的图片ID即可 - 需要响应Marker点击事件的话,给
_annotationManager设置onPointAnnotationTap回调即可,可在回调中触发弹窗、页面跳转等逻辑 - 如果需要持久化Marker,只需要把存储Marker坐标的列表存到本地存储,下次进入页面重新遍历添加即可
内容的提问来源于stack exchange,提问作者Omar Sayed
相关产品推荐
相关产品推荐

