Flutter GoogleMap实现中心固定Marker 拖拽结束拾取新位置
Flutter google_maps_flutter 固定中心选点实现方案
你之前通过onCameraMove回调实时更新Marker坐标的实现思路本身就走偏了,既会产生不必要的性能开销,还容易出现拖拽时Marker跟手延迟、漂移的问题,完全达不到预期交互。正确实现不需要让Marker随地图移动,核心逻辑如下:
- 放弃把中心选点标识做成地图内Marker的思路,用
Stack组件把选点标识直接叠在地图组件的正上方居中位置,地图拖拽时这个标识完全不受地图渲染影响,天然固定在屏幕中心 - 仅监听相机停止移动的回调,在相机静止后再获取当前地图中心的经纬度,完成选点逻辑,拖拽过程中不做任何和选点坐标相关的状态更新
核心可运行代码
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:flutter/material.dart'; class LocationPickerPage extends StatefulWidget { const LocationPickerPage({super.key}); @override State<LocationPickerPage> createState() => _LocationPickerPageState(); } class _LocationPickerPageState extends State<LocationPickerPage> { GoogleMapController? _mapController; LatLng? _finalSelectedLocation; // 初始相机位置,可替换为你当前的定位坐标 final CameraPosition _initCameraPos = const CameraPosition( target: LatLng(31.2304, 121.4737), zoom: 16, ); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('选择位置')), body: Stack( alignment: Alignment.center, children: [ // 底层:谷歌地图组件 GoogleMap( initialCameraPosition: _initCameraPos, zoomControlsEnabled: false, myLocationButtonEnabled: true, onMapCreated: (controller) { _mapController = controller; }, // 拖拽开始时的回调,可选:用来做选点图标动画 onCameraMoveStarted: () { // 这里可以加选点图标上浮的动画逻辑 }, // *重点:不要在onCameraMove回调里做任何坐标更新操作* // 相机停止移动后才触发选点逻辑 onCameraIdle: () async { if (_mapController == null) return; // 获取当前地图可视区域,计算得到精确的中心坐标 final visibleRegion = await _mapController!.getVisibleRegion(); final centerLat = (visibleRegion.northeast.latitude + visibleRegion.southwest.latitude) / 2; final centerLng = (visibleRegion.northeast.longitude + visibleRegion.southwest.longitude) / 2; setState(() { _finalSelectedLocation = LatLng(centerLat, centerLng); }); // 后续可在这里加逆地理编码、地址解析等业务逻辑 // 这里可以加选点图标下落归位的动画逻辑 }, ), // 上层:固定在屏幕中心的选点标识,永远不会随地图移动 // 可以替换为你自己设计的选点针图片、自定义组件 const Icon( Icons.location_pin, size: 50, color: Colors.red, ), // 底部确认选点按钮可自行在Stack里加定位 ], ), ); } }
方案优势
- 流畅度拉满:拖拽地图全程不会触发选点标识的位置更新,没有多余的状态刷新,不会出现卡顿
- 交互完全匹配需求:选点标识始终固定在屏幕正中心,和主流打车、外卖类APP的选点交互完全一致
- 自定义灵活:中心选点标识不受谷歌地图Marker的样式限制,可以随便换图标、加交互动画,比如拖拽时图标上浮、停止时下落的弹性效果
注意避坑
- 不要在
onCameraMove回调里高频更新坐标,这个回调在拖拽过程中每帧都会触发,大量无关setState会直接导致页面掉帧 - 优先通过
getVisibleRegion()计算中心坐标,不要直接存onCameraMove返回的最后一个坐标,避免手势中断、快速滑动时出现坐标偏差 - 如果需要支持点击地图选点,只要在
onTap回调里调用_mapController.animateCamera()把相机移动到点击的坐标即可,相机动画结束后onCameraIdle会自动触发选点逻辑,不需要额外处理
内容的提问来源于stack exchange,提问作者Ali Punjabi
相关产品推荐
相关产品推荐

