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

Flutter中如何等待另一个类返回的年份选择值?

Flutter年份选择器await后无法正确获取返回值问题

问题场景

按钮点击事件代码:

alignment: Alignment.centerRight,
onPressed: () async {
  print(selectedYear);

  selectedYear = await int.tryParse(
      SetYear(context: context, selectedYear: selectedYear!)
          .setYear()
          .toString());
  print(selectedYear);
},
icon: Icon(Icons.calendar_month_outlined)),

执行后打印顺序为:

flutter: 2023
flutter: null
flutter: Check
flutter: From inside
flutter: 2022

首次打印selectedYear为2023,但await后第二次打印却为null,且SetYear类内的打印内容在第二次打印之后才输出。

SetYear类代码:

class SetYear {
  BuildContext context;
  int selectedYear = 0;

  SetYear({
    required this.context,
    required this.selectedYear,
  });

  Future setYear() async {
    DateTime _selectedDate = DateFormat("yyyy").parse("$selectedYear");
   await showDialog(
      context: context,
      builder: (BuildContext context) {
        print("Check");
        return AlertDialog(
          title: Text("Auswahl Jahr"),
          content: Container(
            // Need to use container to add size constraint.
            width: 300,
            height: 300,
            child: YearPicker(
              firstDate: DateTime(2021),
              lastDate: DateTime(2050),
              initialDate: DateTime.now(),
              selectedDate: _selectedDate,
              onChanged: (DateTime newYear) {
                if (newYear != _selectedDate) {
                  selectedYear =
                      int.tryParse("${DateFormat("yyyy").format(newYear)}") ??
                          2022;
                }
                // close the dialog when year is selected.
                Navigator.pop(context);
              },
            ),
          ),
        );
      },
    );
    print("From inside");
    print(selectedYear);
    return Future.value(selectedYear);
  }
}

问题原因

  1. 返回值处理错误:调用setYear()后直接调用.toString(),但setYear()返回的是Future<int>,转字符串后会变成Instance of 'Future<int>',用int.tryParse解析必然得到null,这是第二次打印null的核心原因。
  2. 异步逻辑被破坏:错误的字符串转换操作导致await的正常逻辑失效,提前拿到了无效值,进而出现打印顺序混乱的情况。

解决方案

方案1:修正外部调用逻辑

直接awaitsetYear()的返回值,无需额外的字符串转换和解析,因为setYear()本身就返回Future<int>:

onPressed: () async {
  print(selectedYear);
  // 直接await获取int类型的返回值
  selectedYear = await SetYear(context: context, selectedYear: selectedYear!).setYear();
  print(selectedYear);
},

方案2:优化SetYear类逻辑(可选,提升代码严谨性)

通过showDialog的返回值传递选中年份,避免依赖类成员变量修改,逻辑更清晰:

class SetYear {
  BuildContext context;
  int selectedYear;

  SetYear({
    required this.context,
    required this.selectedYear,
  });

  Future<int> setYear() async {
    DateTime _selectedDate = DateFormat("yyyy").parse("$selectedYear");
    // 用showDialog的返回值接收选中的年份
    final result = await showDialog<int>(
      context: context,
      builder: (BuildContext context) {
        print("Check");
        return AlertDialog(
          title: Text("Auswahl Jahr"),
          content: Container(
            width: 300,
            height: 300,
            child: YearPicker(
              firstDate: DateTime(2021),
              lastDate: DateTime(2050),
              initialDate: DateTime.now(),
              selectedDate: _selectedDate,
              onChanged: (DateTime newYear) {
                int newSelectedYear = int.tryParse(DateFormat("yyyy").format(newYear)) ?? 2022;
                // 关闭弹窗时直接返回选中的年份
                Navigator.pop(context, newSelectedYear);
              },
            ),
          ),
        );
      },
    );
    // 处理用户未选择直接关闭弹窗的情况,返回原年份
    final finalYear = result ?? selectedYear;
    print("From inside");
    print(finalYear);
    return finalYear;
  }
}

外部调用保持方案1的写法即可,这样能彻底避免类成员变量修改带来的意外问题。

验证效果

修改后打印顺序会变为:

flutter: 2023
flutter: Check
flutter: From inside
flutter: 2022
flutter: 2022

此时第二次打印的selectedYear就是用户选中的年份,实现了等待年份选择完成后再获取值的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 18:42:45