Flutter导航问题:PlanDaysExList判断错误导致始终跳转错误页面
问题分析与解决
需求与问题
- 需求:存储训练内容的
PlanDaysExList为空时,页面跳转至restScreen;列表存在内容时,跳转至getPlanExercisesScreen。 - 问题:无论列表是否为空,始终跳转至
getPlanExercisesScreen,空列表时该页面无训练内容显示。
相关代码
DaysDetails组件代码
Widget DaysDetails(context,index,weekNum) => InkWell( onTap: () { LifeStyleCubit.get(context).PlanDaysExList=[]; LifeStyleCubit.get(context).getPlanDaysExercises( planName: model.planName, weekNum: weekNum+1, dayNum: index + 1, ); if(LifeStyleCubit.get(context).PlanDaysExList==[]) {Navigator.push(context, MaterialPageRoute( builder: (context)=>restScreen()));} else{Navigator.push(context, MaterialPageRoute( builder: (context)=>getPlanExercisesScreen()));} }, child: SizedBox( height: 35,width: 100, child: Container( color: Colors.orange, child: Center(child: Text('Day ${index+1}')), ), ), );
getPlanDaysExercises方法代码
void getPlanDaysExercises({ required int weekNum, required int dayNum, required String planName, }) { FirebaseFirestore.instance .collection('users') .doc(uId) .collection('plans') .doc(planName) .collection('week $weekNum') .doc('week $weekNum') .collection('days') .get() .then((value){ PlanDaysExList.clear(); value.docs.forEach((element) { if(element.data()['day'] == dayNum) { PlanDaysExList.add(PlanExercisesModel.fromJson(element.data())); } });
问题根源
- 异步操作时机错误:
getPlanDaysExercises中的Firestore查询是异步操作,调用该方法后会立即执行后续的if判断,此时PlanDaysExList还未被异步请求修改,仍为初始空数组。 - 数组为空判断逻辑错误:Dart中使用
==[]判断数组为空是错误的,因为==比较的是对象引用。你创建的新空数组[]和PlanDaysExList的引用不同,所以这个判断永远返回false,导致else分支(跳转至getPlanExercisesScreen)始终执行。
解决方案
步骤1:修正数组为空的判断方式
使用Dart列表的isEmpty属性判断列表是否为空,这是官方推荐的正确方式。
步骤2:确保异步请求完成后再执行跳转逻辑
将跳转逻辑放在异步请求完成之后,使用async/await实现更易读的异步控制流。
修改后的getPlanDaysExercises方法
将方法改为返回Future<void>,使用await等待Firestore查询完成:
Future<void> getPlanDaysExercises({ required int weekNum, required int dayNum, required String planName, }) async { final querySnapshot = await FirebaseFirestore.instance .collection('users') .doc(uId) .collection('plans') .doc(planName) .collection('week $weekNum') .doc('week $weekNum') .collection('days') .get(); PlanDaysExList.clear(); querySnapshot.docs.forEach((element) { if(element.data()['day'] == dayNum) { PlanDaysExList.add(PlanExercisesModel.fromJson(element.data())); } }); }
修改后的Days组件onTap逻辑
在onTap回调中使用async/await等待数据加载完成,再进行判断和跳转:
Widget DaysDetails(context, index, weekNum) => InkWell( onTap: () async { final cubit = LifeStyleCubit.get(context); cubit.PlanDaysExList = []; // 等待异步数据加载完成 await cubit.getPlanDaysExercises( planName: model.planName, weekNum: weekNum + 1, dayNum: index + 1, ); // 正确判断列表是否为空 if(cubit.PlanDaysExList.isEmpty) { Navigator.push(context, MaterialPageRoute(builder: (context) => restScreen())); } else { Navigator.push(context, MaterialPageRoute(builder: (context) => getPlanExercisesScreen())); } }, child: SizedBox( height: 35, width: 100, child: Container( color: Colors.orange, child: Center(child: Text('Day ${index+1}')), ), ), );
内容的提问来源于stack exchange,提问作者hazem saad
相关产品推荐
相关产品推荐

