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

Flutter Google Maps:初始化器中无法访问widget经纬度问题

解决Flutter中「无法在初始化器中访问widget」的问题

问题根源在于:State类的成员变量初始化阶段,widget对象还未完成初始化,所以你不能直接在成员变量声明时用widget.lat和widget.lang来初始化userLocation。

下面是最简洁可行的修复方案:

修复代码示例

用late关键字标记userLocation,延迟到initState方法中完成赋值(此时widget已经可用),调整后的完整代码如下:

class CalculateDistance extends StatefulWidget {
  const CalculateDistance({super.key, required this.lang, required this.lat});

  final double lang;
  final double lat;
  @override
  // ignore: library_private_types_in_public_api
  _CalculateDistanceState createState() => _CalculateDistanceState();
}

class _CalculateDistanceState extends State<CalculateDistance> {
  GoogleMapController? mapController; //控制器:Google地图
  PolylinePoints polylinePoints = PolylinePoints();

  String googleAPiKey = "YOUR_API_KEY";

  Set<Marker> markers = {}; //地图标记集合
  Map<PolylineId, Polyline> polylines = {}; //路线绘制集合
  LatLng storeLocation =
      const LatLng(-30.600164342582726, 23.508854043469647); //店铺位置
  // 用late延迟初始化,后续在initState中赋值
  late LatLng userLocation; //用户位置

  double distance = 0.0;

  @override
  void initState() {
    // 先初始化userLocation,此时widget已可用
    userLocation = LatLng(widget.lat, widget.lang);
    
    markers.add(Marker(
      //添加店铺位置标记
      markerId: MarkerId(storeLocation.toString()),
      position: storeLocation,
      infoWindow: const InfoWindow(
        title: '店铺位置',
        snippet: '店铺标记',
      ),
      icon: BitmapDescriptor.defaultMarker,
    ));

    markers.add(Marker(
      //添加用户位置标记
      markerId: MarkerId(userLocation.toString()),
      position: userLocation,
      infoWindow: const InfoWindow(
        title: '用户位置',
        snippet: '用户标记',
      ),
      icon: BitmapDescriptor.defaultMarker,
    ));

    getDirections(); //调用接口获取路线数据

    super.initState();
  }

  getDirections() async {
    List<LatLng> polylineCoordinates = [];

    PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
      googleAPiKey,
      PointLatLng(storeLocation.latitude, storeLocation.longitude),
      PointLatLng(userLocation.latitude, userLocation.longitude),
      travelMode: TravelMode.driving,
    );

    if (result.points.isNotEmpty) {
      for (var point in result.points) {
        polylineCoordinates.add(LatLng(point.latitude, point.longitude));
      }
    } else {
      print(result.errorMessage);
    }

    //计算总距离
    double totalDistance = 0;
    for (var i = 0; i < polylineCoordinates.length - 1; i++) {
      totalDistance += calculateDistance(
          polylineCoordinates[i].latitude,
          polylineCoordinates[i].longitude,
          polylineCoordinates[i + 1].latitude,
          polylineCoordinates[i + 1].longitude);
    }
    print(totalDistance);

    setState(() {
      distance = totalDistance;
    });

    //添加路线到地图
    addPolyLine(polylineCoordinates);
  }

  addPolyLine(List<LatLng> polylineCoordinates) {
    PolylineId id = const PolylineId("poly");
    Polyline polyline = Polyline(
      polylineId: id,
      color: Colors.deepPurpleAccent,
      points: polylineCoordinates,
      width: 8,
    );
    polylines[id] = polyline;
    setState(() {});
  }

  double calculateDistance(lat1, lon1, lat2, lon2) {
    var p = 0.017453292519943295;
    var a = 0.5 -
        cos((lat2 - lat1) * p) / 2 +
        cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2;
    return 12742 * asin(sqrt(a));
  }
  // 下方Scaffold代码保持不变
}

关键改动说明

  1. 用late修饰userLocation,告诉Dart该变量会在使用前完成初始化
  2. 在initState方法开头先赋值userLocation,此时widget已经可以正常访问传递过来的经纬度
  3. 后续所有依赖userLocation的逻辑(添加标记、计算路线)都能正常获取到正确值

内容的提问来源于stack exchange,提问作者Ali Akbar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:01:01