Flutter中如何实现Google Map可拖拽且标记始终居中?
在Flutter中实现拖拽地图时标记固定中心并获取经纬度(类似Uber效果)
步骤1:添加依赖
在项目的pubspec.yaml文件中添加google_maps_flutter依赖:
dependencies: flutter: sdk: flutter google_maps_flutter: ^2.5.0 # 替换为最新版本
执行flutter pub get完成依赖安装。
步骤2:配置Google Maps API密钥
- Android:在
android/app/src/main/AndroidManifest.xml的<application>标签内添加:<meta-data android:name="com.google.android.geo.API_KEY" android:value="你的Google Maps API密钥"/> - iOS:在
ios/Runner/Info.plist中添加:<key>GoogleMapsAPIKey</key> <string>你的Google Maps API密钥</string>
步骤3:核心实现代码
用Stack组件将地图与固定在屏幕中心的标记图标叠加,监听地图相机移动结束事件获取中心经纬度:
import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; class MapPickerScreen extends StatefulWidget { const MapPickerScreen({super.key}); @override State<MapPickerScreen> createState() => _MapPickerScreenState(); } class _MapPickerScreenState extends State<MapPickerScreen> { late GoogleMapController _mapController; LatLng _currentCenter = const LatLng(37.7749, -122.4194); // 默认旧金山坐标 // 地图初始化完成回调 void _onMapCreated(GoogleMapController controller) { _mapController = controller; } // 相机移动结束时获取中心坐标 void _onCameraIdle() async { final cameraPosition = await _mapController.getCameraPosition(); setState(() { _currentCenter = cameraPosition.target; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('地图位置选择')), body: Stack( alignment: Alignment.center, children: [ // Google地图组件 GoogleMap( onMapCreated: _onMapCreated, initialCameraPosition: CameraPosition( target: _currentCenter, zoom: 15, ), onCameraIdle: _onCameraIdle, // 可按需调整交互选项 myLocationButtonEnabled: false, zoomControlsEnabled: true, ), // 固定在屏幕中心的标记图标(替代地图自带Marker) const Icon( Icons.location_on, color: Colors.red, size: 40, ), // 显示当前中心经纬度的悬浮层 Positioned( bottom: 20, left: 16, right: 16, child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 4)], ), child: Text( '当前位置:${_currentCenter.latitude.toStringAsFixed(6)}, ${_currentCenter.longitude.toStringAsFixed(6)}', style: const TextStyle(fontSize: 16), ), ), ), ], ), ); } } // 示例入口 void main() => runApp(const MaterialApp(home: MapPickerScreen()));
关键逻辑说明
- 固定标记:通过
Stack将Icon组件固定在屏幕中心,而非使用Google Map自带的Marker——地图自带Marker会随地图拖拽移动,无法实现固定在屏幕中心的效果。 - 获取经纬度:监听
onCameraIdle事件(用户停止拖拽/缩放地图后触发),通过GoogleMapController.getCameraPosition()获取当前相机的目标坐标,即屏幕中心对应的地理经纬度。 - 实时更新:通过
setState更新_currentCenter,同步显示最新的经纬度信息。
内容的提问来源于stack exchange,提问作者Andrew Piterov
相关产品推荐
相关产品推荐

