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

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()));
        }
      });

问题根源

  1. 异步操作时机错误:getPlanDaysExercises中的Firestore查询是异步操作,调用该方法后会立即执行后续的if判断,此时PlanDaysExList还未被异步请求修改,仍为初始空数组。
  2. 数组为空判断逻辑错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:27:58