Flutter使用google_maps_flutter时addMarker等方法未定义报错如何解决
问题根因
你当前使用的google_maps_flutter为2.0+以上版本,该版本对标记管理逻辑做了破坏性更新:废弃了通过GoogleMapController直接增删标记的API,也移除了MarkerOptions、InfoWindowText类,你参考的是旧版本的实现代码,因此触发上述报错。
修复步骤
- 新增
Set<Marker>类型的状态变量管理所有地图标记,新版本标记通过GoogleMap组件的markers参数直接渲染,无需通过控制器操作 - 所有
MarkerOptions替换为Marker类,配置参数直接传入Marker构造方法 - 所有
InfoWindowText替换为InfoWindow类,title和snippet参数对应原有文本配置 - 移除
mapController.addMarker、mapController.clearMarkers调用,改为直接操作标记集合后调用setState更新页面 - 补充修正代码中其他空安全、参数类型不匹配的问题
修正后完整代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:geoflutterfire/geoflutterfire.dart'; import 'package:rxdart/rxdart.dart'; import 'package:location/location.dart'; import 'dart:async'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold( body: FireMap(), ) ); } } class FireMap extends StatefulWidget { const FireMap({Key? key}) : super(key: key); @override State createState() => FireMapState(); } class FireMapState extends State<FireMap> { late GoogleMapController mapController; Location location = Location(); FirebaseFirestore firestore = FirebaseFirestore.instance; Geoflutterfire geo = Geoflutterfire(); // 标记管理集合 Set<Marker> markers = {}; // Stateful Data BehaviorSubject<double> radius = BehaviorSubject.seeded(100.0); late Stream<dynamic> query; // Subscription late StreamSubscription subscription; @override Widget build(context) { return Stack(children: [ GoogleMap( initialCameraPosition: const CameraPosition( target: LatLng(24.142, -110.321), zoom: 15 ), onMapCreated: _onMapCreated, myLocationEnabled: true, mapType: MapType.hybrid, compassEnabled: true, markers: markers, ), Positioned( bottom: 50, right: 10, child: TextButton( style: TextButton.styleFrom(backgroundColor: Colors.green), child: const Icon(Icons.pin_drop, color: Colors.white), onPressed: _addGeoPoint ) ), Positioned( bottom: 50, left: 10, child: Slider( min: 100.0, max: 500.0, divisions: 4, value: radius.value, label: 'Radius ${radius.value}km', activeColor: Colors.green, inactiveColor: Colors.green.withOpacity(0.2), onChanged: _updateQuery, ) ) ]); } _onMapCreated(GoogleMapController controller) { _startQuery(); _animateToUser(); setState(() { mapController = controller; }); } addMarker() { final Marker marker = Marker( markerId: MarkerId(DateTime.now().millisecondsSinceEpoch.toString()), position: mapController.cameraPosition.target, icon: BitmapDescriptor.defaultMarker, infoWindow: InfoWindow.noText, ); setState(() { markers.add(marker); }); } _animateToUser() async { var pos = await location.getLocation(); mapController.animateCamera(CameraUpdate.newCameraPosition( CameraPosition( target: LatLng(pos.latitude ?? 24.142, pos.longitude ?? -110.321), zoom: 17.0, ) ) ); } Future<DocumentReference> _addGeoPoint() async { var pos = await location.getLocation(); GeoFirePoint point = geo.point(latitude: pos.latitude ?? 24.142, longitude: pos.longitude ?? -110.321); return firestore.collection('locations').add({ 'position': point.data, 'name': 'Yay I can be queried!' }); } void _updateMarkers(List<DocumentSnapshot> documentList) { print(documentList); setState(() { markers.clear(); }); for (var document in documentList) { Map<String, dynamic> data = document.data() as Map<String, dynamic>; GeoPoint pos = data['position']['geopoint']; double distance = data['distance']; var marker = Marker( markerId: MarkerId(document.id), position: LatLng(pos.latitude, pos.longitude), icon: BitmapDescriptor.defaultMarker, infoWindow: InfoWindow(title: 'Magic Marker', snippet: '$distance kilometers from query center') ); setState(() { markers.add(marker); }); } } _startQuery() async { // 获取用户位置 var pos = await location.getLocation(); double lat = pos.latitude ?? 24.142; double lng = pos.longitude ?? -110.321; var ref = firestore.collection('locations'); GeoFirePoint center = geo.point(latitude: lat, longitude: lng); subscription = radius.switchMap((rad) { return geo.collection(collectionRef: ref).within( center: center, radius: rad, field: 'position', strictMode: true ); }).listen(_updateMarkers); } _updateQuery(value) { final zoomMap = { 100.0: 12.0, 200.0: 10.0, 300.0: 7.0, 400.0: 6.0, 500.0: 5.0 }; final zoom = zoomMap[value] ?? 12.0; mapController.moveCamera(CameraUpdate.zoomTo(zoom)); setState(() { radius.add(value); }); } @override dispose() { subscription.cancel(); super.dispose(); } }
内容的提问来源于stack exchange,提问作者M.Jehan
相关产品推荐
相关产品推荐

