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); } }
问题原因
- 返回值处理错误:调用
setYear()后直接调用.toString(),但setYear()返回的是Future<int>,转字符串后会变成Instance of 'Future<int>',用int.tryParse解析必然得到null,这是第二次打印null的核心原因。 - 异步逻辑被破坏:错误的字符串转换操作导致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
相关产品推荐
相关产品推荐

