Flutter中Google Maps用户位置与标记点间Polyline绘制失败求助
Flutter Google Maps Polyline 不显示问题修复方案
问题核心原因
- 初始化时机错误:
initState中直接调用setPolylines(),此时地图控制器未完成初始化,且初始标记点会被后续用户位置覆盖,导致生成的路线基于静态初始坐标而非实际位置。 - 标记更新后未同步更新路线:点击定位按钮更新用户位置标记后,未重新调用路线生成方法,路线始终停留在旧坐标。
- 旧数据累积:每次生成路线前未清空旧的坐标列表和Polyline集合,导致数据重复或异常。
- API配置遗漏:未确认Google Cloud控制台是否启用Directions API,或密钥权限配置错误。
修复步骤
- 调整初始化流程:在地图初始化完成(
onMapCreated回调)后再生成路线。 - 更新位置后重新生成路线:点击定位按钮更新用户位置后,立即调用
setPolylines()刷新路线。 - 清空旧数据:每次生成路线前清空坐标列表和Polyline集合,避免数据污染。
- 验证API配置:确保Google Cloud控制台已启用Directions API,且密钥配置了正确的应用访问权限。
修改后的完整代码
class OrderTrackingPageState extends State<OrderTrackingPage> { final Completer<GoogleMapController> _controller = Completer(); Set<Polyline> _polylines = {}; List<LatLng> polylineCoordinates = []; PolylinePoints polylinePoints = PolylinePoints(); final List<Marker> _markers = <Marker>[ Marker( markerId: const MarkerId('1'), position: const LatLng(33.31271476080750, 44.35060022264830), infoWindow: const InfoWindow(title: 'sourceLocation')), Marker( markerId: const MarkerId('2'), position: const LatLng(33.305691, 44.369390), infoWindow: const InfoWindow(title: 'destination')), ]; void setPolylines() async { // 清空旧数据,避免累积异常 polylineCoordinates.clear(); _polylines.clear(); PolylineResult result = await polylinePoints.getRouteBetweenCoordinates( 'AIzaSyBzQ****************EHTKlEOWB8zJLg', // 替换为你的有效Google Map密钥 PointLatLng(_markers[0].position.latitude, _markers[0].position.longitude), PointLatLng(_markers[1].position.latitude, _markers[1].position.longitude), ); if (result.status == 'ok') { for (var point in result.points) { polylineCoordinates.add(LatLng(point.latitude, point.longitude)); } setState(() { _polylines.add(Polyline( polylineId: const PolylineId("polyline"), points: polylineCoordinates, color: const Color(0xFF7B61FF), width: 6, )); }); } else { // 打印错误信息方便排查 print('获取路线失败:${result.errorMessage}'); } } @override void initState() { super.initState(); // 先获取用户位置更新标记 getUserCurrentLocation().then((value) { setState(() { _markers[0] = Marker( markerId: const MarkerId("1"), position: LatLng(value.latitude, value.longitude), infoWindow: const InfoWindow(title: '我的位置'), ); }); }); } @override Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton( backgroundColor: Colors.grey, child: const Icon(Icons.my_location), onPressed: () async { Position value = await getUserCurrentLocation(); print('${value.latitude} ${value.longitude}'); setState(() { _markers[0] = Marker( markerId: const MarkerId("1"), position: LatLng(value.latitude, value.longitude), infoWindow: const InfoWindow(title: '我的位置'), ); }); // 更新地图视角 final GoogleMapController controller = await _controller.future; controller.animateCamera(CameraUpdate.newCameraPosition(CameraPosition( target: LatLng(value.latitude, value.longitude), zoom: 14, ))); // 更新位置后立即刷新路线 setPolylines(); }, ), body: GoogleMap( initialCameraPosition: CameraPosition( target: LatLng(_markers[0].position.latitude, _markers[0].position.longitude), zoom: 13.5, ), polylines: _polylines, markers: Set<Marker>.of(_markers), onMapCreated: (mapController) { _controller.complete(mapController); // 地图初始化完成后生成路线 setPolylines(); }, myLocationEnabled: true, myLocationButtonEnabled: false, zoomGesturesEnabled: true, zoomControlsEnabled: true, ), ); } Future<Position> getUserCurrentLocation() async { LocationPermission permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); } return await Geolocator.getCurrentPosition(); } }
额外配置检查
- pubspec.yaml依赖:确保已添加所需包
dependencies: flutter: sdk: flutter google_maps_flutter: ^2.5.0 flutter_polyline_points: ^2.0.0 geolocator: ^10.1.0 - Android权限:在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - iOS权限描述:在
Info.plist中添加<key>NSLocationWhenInUseUsageDescription</key> <string>需要访问您的位置以显示路线</string>
内容的提问来源于stack exchange,提问作者reem rasem
相关产品推荐
相关产品推荐

