You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:54:04