Flutter如何实现Google Map选取地址并在组件中展示的功能
Flutter Google Map 地址选取功能实现方案
1. 前置依赖配置
首先在pubspec.yaml中添加所需依赖:
- google_maps_flutter:用于Google地图渲染
- geocoding:用于经纬度和实际地址的互转
- 已配置好Google Cloud平台的Maps相关服务API密钥到Android/iOS项目中
2. 基础状态变量定义
在当前页面的State类中提前定义所需全局变量:
// 选中后展示的地址文本 String address = ""; // 地图控制器完成器 final Completer<GoogleMapController> _controller = Completer(); // 初始地图位置,示例为北京天安门坐标,可替换为自定义初始位置 static const CameraPosition _initialcameraposition = CameraPosition( target: LatLng(39.9042, 116.4074), zoom: 14.5, );
3. 现有Widget逻辑补全
你现有代码中GoogleMap的onTap回调补全跳转地址选择页、接收返回结果转地址的逻辑:
Column( children: [ Container( height: 200, width: double.infinity, child: GoogleMap( mapType: MapType.normal, initialCameraPosition: _initialcameraposition, onMapCreated: (GoogleMapController controller) { _controller.complete(controller); }, onTap: (LatLng location) async { // 跳转到地址选择页面,等待返回选中的经纬度 final selectedLatLng = await Navigator.push( context, MaterialPageRoute(builder: (context) => const LocationPickerPage()), ); if (selectedLatLng != null) { // 经纬度转实际地址文本 List<Placemark> placemarks = await placemarkFromCoordinates( selectedLatLng.latitude, selectedLatLng.longitude, ); if (placemarks.isNotEmpty) { Placemark place = placemarks.first; // 可根据业务需求调整地址拼接字段 setState(() { address = "${place.country} ${place.administrativeArea} ${place.locality} ${place.street}"; }); } } }, ), ), Text(address.isNotEmpty ? address : "请点击地图选择地址") ], )
4. 地址选择页面实现
新建LocationPickerPage StatefulWidget,实现带搜索、标记功能的地址选择页:
class LocationPickerPage extends StatefulWidget { const LocationPickerPage({super.key}); @override State<LocationPickerPage> createState() => _LocationPickerPageState(); } class _LocationPickerPageState extends State<LocationPickerPage> { final Completer<GoogleMapController> _mapController = Completer(); LatLng? _selectedLocation; final TextEditingController _searchController = TextEditingController(); // 可复用初始位置常量,也可单独定义 static const CameraPosition _initialPos = CameraPosition( target: LatLng(39.9042, 116.4074), zoom: 14.5, ); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("选择地址"), actions: [ IconButton( icon: const Icon(Icons.check), onPressed: _selectedLocation == null ? null : () { // 将选中的经纬度返回上一级页面 Navigator.pop(context, _selectedLocation); }, ) ], ), body: Column( children: [ // 地址搜索框 Padding( padding: const EdgeInsets.all(8.0), child: TextField( controller: _searchController, decoration: const InputDecoration( hintText: "输入地址搜索", prefixIcon: Icon(Icons.search), border: OutlineInputBorder(), ), onSubmitted: (value) async { if (value.trim().isEmpty) return; // 搜索地址转经纬度,移动地图到目标位置 List<Location> locations = await locationFromAddress(value); if (locations.isNotEmpty) { final target = LatLng(locations.first.latitude, locations.first.longitude); final controller = await _mapController.future; controller.animateCamera(CameraUpdate.newLatLngZoom(target, 16)); setState(() { _selectedLocation = target; }); } }, ), ), Expanded( child: GoogleMap( mapType: MapType.normal, initialCameraPosition: _initialPos, onMapCreated: (controller) => _mapController.complete(controller), onTap: (latLng) { // 点击地图选中位置,添加标记 setState(() { _selectedLocation = latLng; }); }, markers: _selectedLocation == null ? {} : { Marker( markerId: const MarkerId("selected-location"), position: _selectedLocation!, ), }, ), ), ], ), ); } }
可选优化点
- 可添加定位权限申请,默认定位到用户当前位置作为初始位置
- 地址拼接规则可根据业务需求调整,比如增加邮编、门牌号等字段
- 国内环境使用可替换为高德、百度等国内地图服务适配使用
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

