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

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时未做非空处理,可通过以下步骤修复:

  1. 将Marker和Circle声明为可空类型:使用Marker? marker和Circle? circle,明确标记它们可能为null;
  2. 构建Set时处理空值:使用非空断言!(确保调用getCurrentLocation后值已初始化),或者通过空值判断过滤空值;
  3. 可选优化:将_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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:33:28