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代码保持不变 }
关键改动说明
- 用
late修饰userLocation,告诉Dart该变量会在使用前完成初始化 - 在
initState方法开头先赋值userLocation,此时widget已经可以正常访问传递过来的经纬度 - 后续所有依赖
userLocation的逻辑(添加标记、计算路线)都能正常获取到正确值
内容的提问来源于stack exchange,提问作者Ali Akbar
相关产品推荐
相关产品推荐

