Flutter中Google Map Marker初始化报错问题求助
解决Flutter Google Map Marker初始化错误
问题描述
在集成Google Map时遇到以下Marker/Circle初始化相关错误:
- 直接定义
Marker marker时,编辑器提示“marker should be initialise”; - 使用
late Marker marker时,编辑器无报错,但运行App出现LateInitializationError: Field marker has not been initialized; - 使用
Marker? marker时,在markers: Set.of((marker != null) ? [marker] : [])代码处,出现错误提示“The element type 'Marker?' can't be assigned to the list type 'Marker'”。
依赖版本:
- google_maps_flutter: ^2.2.0
- location: ^4.4.0
解决方案
核心问题是Marker和Circle在Widget初始化阶段未被赋值,且可空类型在存入Set时未做非空处理,可通过以下步骤修复:
- 将Marker和Circle声明为可空类型:使用
Marker? marker和Circle? circle,明确标记它们可能为null; - 构建Set时处理空值:使用非空断言
!(确保调用getCurrentLocation后值已初始化),或者通过空值判断过滤空值; - 可选优化:将
_locationSubscription改为可空类型,用可选链调用替代冗余的空判断,简化代码。
修改后的完整代码
// ignore_for_file: use_key_in_widget_constructors, prefer_final_fields, prefer_const_constructors, duplicate_ignore, camel_case_types, unnecessary_new, unnecessary_this, unnecessary_null_comparison import 'dart:async'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:location/location.dart'; class map extends StatefulWidget { @override State<map> createState() => mapState(); } class mapState extends State<map> { late GoogleMapController _controller; LatLng? latlng; StreamSubscription? _locationSubscription; Location _locationTracker = Location(); Marker? marker; Circle? circle; static const CameraPosition _kGooglePlex = CameraPosition( target: LatLng(37.42796133580664, -122.085749655962), zoom: 15, ); Future<Uint8List> getMarker() async { ByteData byteData = await DefaultAssetBundle.of(context).load("assets/car_icon.png"); return byteData.buffer.asUint8List(); } static final CameraPosition _kLake = CameraPosition( bearing: 192.8334901395799, target: LatLng(37.43296265331129, -122.08832357078792), tilt: 59.440717697143555, zoom: 19.151926040649414); void updateMarkerAndCircle(LocationData newLocalData, Uint8List imageData) { LatLng latlng = LatLng(newLocalData.latitude!, newLocalData.longitude!); setState(() { marker = Marker( markerId: const MarkerId("home"), position: latlng, rotation: newLocalData.heading!, draggable: false, zIndex: 2, flat: true, anchor: const Offset(0.5, 0.5), icon: BitmapDescriptor.fromBytes(imageData)); circle = Circle( circleId: const CircleId("car"), radius: newLocalData.accuracy!, zIndex: 1, strokeColor: Colors.blue, center: latlng, fillColor: Colors.blue.withAlpha(70)); }); } void getCurrentLocation() async { try { Uint8List imageData = await getMarker(); var location = await _locationTracker.getLocation(); updateMarkerAndCircle(location, imageData); _locationSubscription?.cancel(); _locationSubscription = _locationTracker.onLocationChanged.listen((newLocalData) { if (_controller != null) { _controller.animateCamera(CameraUpdate.newCameraPosition(CameraPosition( bearing: 192.8334901395799, target: LatLng(newLocalData.latitude!, newLocalData.longitude!), tilt: 0, zoom: 18.00))); updateMarkerAndCircle(newLocalData, imageData); } }); } on PlatformException catch (e) { if (e.code == 'PERMISSION_DENIED') { debugPrint("Permission Denied"); } } } @override void dispose() { _locationSubscription?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: GoogleMap( mapType: MapType.hybrid, myLocationButtonEnabled: true, myLocationEnabled: true, initialCameraPosition: _kGooglePlex, markers: Set.of(marker != null ? [marker!] : []), circles: Set.of(circle != null ? [circle!] : []), onMapCreated: (GoogleMapController controller) { _controller = controller; }, ), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, floatingActionButton: FloatingActionButton.extended( onPressed: getCurrentLocation, label: const Text('To the lake!'), icon: const Icon(Icons.location_searching), ), ); } }
额外优化说明
- 显式导入
dart:typed_data,避免部分编译环境报错; - 给常量添加
const修饰符,提升代码性能; - 使用可选链调用
_locationSubscription?.cancel()替代冗余的空值判断,代码更简洁。
内容的提问来源于stack exchange,提问作者mahesh parihar
相关产品推荐
相关产品推荐

