如何用FlutterMap实现带居中固定标记的位置选择器?
用FlutterMap实现中心固定标记的位置选择器
要实现标记始终固定在地图中心、实时显示对应经纬度的位置选择器,核心思路是将标记与地图分离布局,同时监听地图状态变化获取中心坐标。以下是具体实现方案:
1. 配置依赖
在pubspec.yaml中添加所需依赖:
dependencies: flutter: sdk: flutter flutter_map: ^6.1.0 # 使用最新稳定版本 latlong2: ^0.9.0 # 处理经纬度数据
2. 核心实现代码
import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:latlong2/latlong.dart'; class CenterMarkerPicker extends StatefulWidget { const CenterMarkerPicker({super.key}); @override State<CenterMarkerPicker> createState() => _CenterMarkerPickerState(); } class _CenterMarkerPickerState extends State<CenterMarkerPicker> { LatLng _currentCenter = const LatLng(39.9042, 116.4074); // 默认初始坐标(北京) final MapController _mapController = MapController(); @override void initState() { super.initState(); _currentCenter = _mapController.center; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('位置选择器')), body: Stack( alignment: Alignment.center, children: [ FlutterMap( mapController: _mapController, options: MapOptions( initialCenter: _currentCenter, initialZoom: 14, onMapEvent: (MapEvent event) { // 监听地图移动、缩放事件,更新中心坐标 if (event is MapEventMove || event is MapEventZoom) { setState(() { _currentCenter = _mapController.center; }); } }, ), children: [ TileLayer( urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', subdomains: const ['a', 'b', 'c'], ), ], ), // 固定在屏幕中心的标记图钉 const Icon( Icons.location_pin, color: Colors.red, size: 40, ), // 底部显示实时经纬度的面板 Positioned( bottom: 20, left: 16, right: 16, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: Colors.white.withOpacity(0.9), borderRadius: BorderRadius.circular(8), boxShadow: const [BoxShadow(blurRadius: 3, color: Colors.black26)], ), child: Text( '当前坐标:\n纬度 ${_currentCenter.latitude.toStringAsFixed(6)},经度 ${_currentCenter.longitude.toStringAsFixed(6)}', textAlign: TextAlign.center, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), ), ), ], ), ); } }
3. 关键细节说明
- 固定标记布局:通过
Stack组件将标记图标与FlutterMap叠加,设置alignment: Alignment.center让标记始终处于屏幕正中心,完全不受地图移动、缩放的影响,比传统的Marker实现更简洁高效。 - 实时坐标获取:利用
onMapEvent监听地图的移动(MapEventMove)和缩放(MapEventZoom)事件,每次事件触发时通过mapController.center获取最新的地图中心经纬度,调用setState更新显示。 - 精度控制:使用
toStringAsFixed(6)保留6位小数,满足大多数位置选择场景的精度需求,可根据实际需求调整位数。 - 瓦片替换:示例使用OpenStreetMap的免费瓦片,可替换为高德、谷歌等其他地图服务商的瓦片,只需修改
TileLayer的urlTemplate即可(注意遵守对应服务商的使用规则)。
内容的提问来源于stack exchange,提问作者user1209216
相关产品推荐
相关产品推荐

