Flutter修改代码后出现StateError及空感知运算符警告求助
问题修复方案
1. 修复Bad state: Future already completed错误
错误原因:Completer<GoogleMapController> _controller在MapsView类中初始化,热重载时build方法重复执行,onMapCreated会再次调用_controller.complete(controller),但Completer对象只能被完成一次,触发状态错误。
修复方法:在onMapCreated回调中先判断Completer是否已完成,仅在未完成时调用complete:
onMapCreated: (GoogleMapController controller) { if (!_controller.isCompleted) { _controller.complete(controller); } },
更贴合GetX架构的优化方案:将GoogleMapController的持有逻辑移到MapsController中,避免在View层维护状态变量。示例:
在MapsController中添加:
final mapController = Completer<GoogleMapController>();
View层直接使用controller.mapController替代原_controller,热重载时控制器状态会被正确管理。
2. 修复空感知运算符警告
警告提示:The receiver can't be null, so the null-aware operator '?[' is unnecessary.,对应代码行listCampus?[i].data()。
原因:此前已通过listCampus!断言listCampus不为空,?[]空感知运算符属于冗余写法。
修复方法:将listCampus?[i]改为listCampus[i],同时注意修复ListView.builder中相同的问题:
// 循环中的修复 var detailCampus = listCampus[i].data()! as Map<String, dynamic>; // ListView.builder中的修复 var detailCampus = listCampus[index].data()! as Map<String, dynamic>;
完整修复后的代码
class MapsView extends GetView<MapsController> { MapsView({Key? key}) : super(key: key); Completer<GoogleMapController> _controller = Completer(); @override Widget build(BuildContext context) { return Scaffold( body: StreamBuilder<QuerySnapshot<Object?>>( stream: controller.getCampus(), builder: (context, snap) { if (snap.connectionState == ConnectionState.waiting) { return Center( child: CircularProgressIndicator(), ); } if (snap.hasData) { var listCampus = snap.data?.docs; for (var i = 0; i < listCampus!.length; i++) { var detailCampus = listCampus[i].data()! as Map<String, dynamic>; String title = detailCampus["nama"]; String snipet = detailCampus["categori"]; double lat = double.parse(detailCampus["latitude"]); double long = double.parse(detailCampus["longitude"]); LatLng latlong = LatLng(lat, long); MarkerId markerId = MarkerId(detailCampus["latitude"] + detailCampus["longitude"]); controller.addMarker(markerId, title, snipet, latlong); } return Stack( children: [ Container( height: Get.height, width: Get.width, child: GoogleMap( mapType: MapType.normal, initialCameraPosition: CameraPosition(target: LatLng(-7.6893549, 110.2408421), zoom: 8), onMapCreated: (GoogleMapController controller) { if (!_controller.isCompleted) { _controller.complete(controller); } }, markers: Set<Marker>.of(controller.allMarkers), ), ), Align( alignment: Alignment.bottomLeft, child: Container( margin: EdgeInsets.symmetric(vertical: 25), height: 150, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: listCampus?.length, itemBuilder: ((context, index) { var detailCampus = listCampus[index].data()! as Map<String, dynamic>; return InkWell( onTap: () async { final GoogleMapController controller = await _controller.future; var lat = double.tryParse(detailCampus['latitude']) ?? 0; var long = double.tryParse(detailCampus['longitude']) ?? 0; controller.animateCamera( CameraUpdate.newCameraPosition( CameraPosition(target: LatLng(lat, long), zoom: 18, tilt: 50, bearing: 45), ), ); }, child: Container( width: 350, height: 150, margin: EdgeInsets.only(right: 12), decoration: BoxDecoration( color: Color(0xffF5f5f5), borderRadius: BorderRadius.circular(16), ), child: Row( children: [ Container( padding: EdgeInsets.all(16), child: Icon( Icons.school, size: 50, ), ), SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 90), Text( "${detailCampus["nama"]}", overflow: TextOverflow.ellipsis, softWrap: false, style: GoogleFonts.signika( fontWeight: FontWeight.bold, fontSize: 16, ), ), SizedBox(height: 5), Text( "${detailCampus["categori"]}", style: GoogleFonts.signika( fontWeight: FontWeight.bold, fontSize: 14, color: Colors.grey, ), ), ], ), ], ), ), ); }), ), ), ), ], ); } else { return Center( child: Text("Error"), ); } }), ); } }
内容的提问来源于stack exchange,提问作者Esa Juniarto
相关产品推荐
相关产品推荐

