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

Flutter的DropdownButtonFormField调用方法后选中值无法保留问题求解

问题根本原因

你出现报错的核心原因是:

  • DropdownButtonFormField要求绑定的value必须是items列表中存在的某个值
  • 默认情况下Dart的自定义类判断相等是按内存引用判断的,就算两个ClassNoSearch对象的所有属性完全一致,只要是不同实例就会被判定为不相等
  • 你每次调用_getData()后会更新classNoList(也就是下拉的items数据源),新返回的classNoList里的ClassNoSearch都是全新实例,你之前保存的_currentClassNoSearch不在新的items列表里,所以触发重复值/找不到值的报错

解决步骤

1. 重写ClassNoSearch类的相等判断逻辑

假设ClassNoSearch的唯一标识是userClassDepartmentId,给类添加==运算符重写和hashCode实现:

class ClassNoSearch {
  final String userClassDepartmentId;
  // 你的其他属性

  ClassNoSearch({required this.userClassDepartmentId, /* 其他参数 */});

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is ClassNoSearch &&
          runtimeType == other.runtimeType &&
          userClassDepartmentId == other.userClassDepartmentId;

  @override
  int get hashCode => userClassDepartmentId.hashCode;
}

如果有多个字段参与唯一判断,hashCode可以用Object.hash(field1, field2, field3)的方式生成。

2. 修改_getData方法,不要清空选中值,而是从新的列表里匹配选中值

删掉_currentClassNoSearch = null的代码,更新完classNoList后,重新匹配选中值:

Future<HomeworkSudo> _getData() {
  // 先保存当前选中值的备份,避免异步执行时被其他操作修改
  final selectedClass = _currentClassNoSearch;
  if (selectedClass == null) {
    return getHomeworkSudo("").then((HomeworkSudo result) {
      setState(() {
        activeHomeworkList = result.activeHomeWork;
        inactiveHomeworkList = result.passivHomeWork;
        classNoList = result.classNo;
      });
      return result;
    });
  } else {
    return getHomeworkSudo(selectedClass.userClassDepartmentId)
        .then((HomeworkSudo result) {
      setState(() {
        activeHomeworkList = result.activeHomeWork;
        inactiveHomeworkList = result.passivHomeWork;
        classNoList = result.classNo;
        // 从新的班级列表里找到和之前选中值相等的实例,重新赋值
        _currentClassNoSearch = classNoList.firstWhere(
          (item) => item == selectedClass,
          orElse: () => null,
        );
      });
      return result;
    });
  }
}

3. 可选优化:确保下拉列表没有重复值

可以在更新classNoList之后做一次去重,避免真的存在相同值的选项触发报错:

classNoList = result.classNo.toSet().toList();

前提是你已经重写了ClassNoSearch的==和hashCode,toSet()才能正确去重。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:57:03