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

Flutter:DropdownButtonFormField2屏幕旋转选中项重置及初始值设置问题

Flutter DropdownButtonFormField2 两个问题的解决方案

问题1:屏幕旋转后选中的财年被重置为初始值

原因

当前代码里selFinancialValue是StatelessWidget的成员变量,屏幕旋转时Widget会重建,成员变量会被重新初始化;同时每次进入FinancialYearList状态分支时,都会遍历列表设置当前财年为选中值,覆盖用户之前的选择。

解决步骤

  1. 将选中状态移至Bloc中存储:让Bloc的状态维护选中的财年值,确保状态在Widget重建(如屏幕旋转)时不会丢失。

    • 修改Bloc的状态类,比如在FinancialYearList中添加selectedValue字段,或利用已有的UpdateDropDown状态保存选中值。
    • 仅在首次加载且无选中值时,才设置当前财年为默认值,否则保留用户已选的值。
  2. 从Bloc状态中读取选中值:在BlocBuilder中直接从状态获取选中值,不再依赖Widget的成员变量。

代码修改示例

调整Bloc状态处理逻辑

@override
Widget build(BuildContext context) {
    context.read<MyAccountBloc>().add(FetchFinancialYearList(selectedCompany.id!));
    return BlocBuilder<MyAccountBloc, MyAccountState>(
        builder: (context, state) {
            dynamic currentSelectedValue;
            List<dynamic>? currentFinancialYearList;

            if(state is FinancialYearList) {
                currentFinancialYearList = state.list;
                // 仅无选中值时,才设置当前财年为默认(可选逻辑)
                if(state.selectedValue == null && currentFinancialYearList != null) {
                    for(dynamic itemFY in currentFinancialYearList) {
                        if(DateTime.now().isBetween(yMdFormat.parse(itemFY['startDate']), yMdFormat.parse(itemFY['endDate']))) {
                            currentSelectedValue = itemFY;
                            break;
                        }
                    }
                } else {
                    currentSelectedValue = state.selectedValue;
                }
            } else if(state is UpdateDropDown) {
                currentSelectedValue = state.selValue;
                // 从Bloc状态同步获取财年列表
                currentFinancialYearList = context.read<MyAccountBloc>().state is FinancialYearList 
                    ? (context.read<MyAccountBloc>().state as FinancialYearList).list 
                    : null;
            } else {
                currentFinancialYearList = null;
                currentSelectedValue = null;
            }

            return MaterialApp(
                home: Scaffold(
                    body: SafeArea(
                        child: Stack(
                            children: [
                                Container(
                                    child: Column(
                                        children: [
                                            SizedBox(height: 3,),
                                            currentFinancialYearList == null 
                                                ? SizedBox() 
                                                : setFinancialPeriodDropDown(context, currentSelectedValue, currentFinancialYearList),
                                            SizedBox(height: 3,),
                                            // 原有Tab相关代码...
                                        ],
                                    ),
                                ),
                                // 原有底部按钮代码...
                            ],
                        )
                    ),
                ),
            );
        }
    );
}

修改下拉菜单方法,接收外部传入的选中值和列表

Widget setFinancialPeriodDropDown(BuildContext context, dynamic selectedValue, List<dynamic> financialYearList) {
    return SizedBox(
        height: 45,
        child: DropdownButtonFormField2<dynamic>(
            isExpanded: true,
            hint: const Text('Select Financial Year',style: TextStyle(fontSize: 14),),
            value: selectedValue,
            items: financialYearList.map((item) => DropdownMenuItem<dynamic>(
                value: item,
                child: Text('${dMyFormat.format(yMdFormat.parse(item['startDate']))} :: ${dMyFormat.format(yMdFormat.parse(item['endDate']))}',
                    style: const TextStyle(fontSize: 14,),
                ),)).toList(),
            validator: (value) {
                if (value == null) {
                    return 'Please select Financial Year.';
                }
            },
            onChanged: (value) {
                context.read<MyAccountBloc>().add(UpdateDropDownEvent(selValue: value));
            },
            onSaved: (value) {},
        ),
    );
}

问题2:页面打开时初始值设为“Select Financial Year”提示文本

解决方法

初始时将选中值设为null,DropdownButtonFormField2会自动显示hint属性中的文本。

具体调整

在FinancialYearList状态处理分支中,移除自动设置当前财年的逻辑,直接将选中值设为null:

if(state is FinancialYearList) {
    currentFinancialYearList = state.list;
    // 初始选中值设为null,显示hint文本
    currentSelectedValue = state.selectedValue ?? null;
}

这样页面打开时,下拉菜单会展示“Select Financial Year”,直到用户手动选择财年。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:25:53