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

Flutter DropdownButton选中值不显示,报DropdownMenuItem同值数量异常问题

问题原因

这个报错触发的核心逻辑是Flutter要求DropdownButton绑定的value值,在给定的DropdownMenuItem列表中必须唯一存在,要么0个要么多个都会触发断言失败,你的代码存在以下几个明确问题:

  • courseItems为外部变量,每次StreamBuilder刷新触发重绘时,你都会重复向列表中添加选项,导致相同value的item重复出现
  • 空判断顺序错误:在遍历完snapshot数据之后才判断数据是否为空,为空时遍历逻辑已经执行会抛出越界错误
  • 循环长度写死为2:如果Firebase返回的课程数量不足2条,直接取下标i=0/1会触发数组越界
  • 未校验selected初始值:如果selected初始赋值不在最终生成的courseItems的value集合中,也会触发该错误
修复步骤
  1. 调整判空顺序,先判断数据合法性再执行遍历逻辑
  2. 每次生成下拉选项前清空courseItems,或者直接在builder内部创建临时选项列表,避免重复累加
  3. 循环长度使用返回数据的实际长度,避免越界,如果你确实只需要最多2条,可以取min(2, listViewCourseRecordList.length)作为循环上限
  4. 校验selected值,如果初始值不在选项列表中,将其重置为null或者第一个选项的value
修复后代码示例
import 'dart:math'; // 用到min函数需要导入该包

return StreamBuilder<List<CoursesRecord>>(
  stream: queryCourseRecord(
    queryBuilder: (courseRecord) => courseRecord.orderBy('${widget.orderBy}', descending: true), limit: 5,
  ),
  builder: (context, snapshot) {
    // 加载态处理
    if (!snapshot.hasData) {
      return Center(
        child: SizedBox(
          width: 50,
          height: 50,
          child: CircularProgressIndicator(
            color: FlutterFlowTheme.primaryColor,
          ),
        ),
      );
    }
    List<CoursesRecord> listViewCourseRecordList = snapshot.data;
    // 优先处理空数据情况
    if (listViewCourseRecordList.isEmpty) {
      return Container(
        height: 100,
        child: Center(
          child: Text('No results.'),
        ),
      );
    }
    // 每次重新生成选项列表,避免重复累加
    List<DropdownMenuItem> courseItems = [];
    // 用实际数据长度作为上限,最多取2条
    int itemCount = min(2, listViewCourseRecordList.length);
    for (int i = 0; i < itemCount; i++) {
      String value = listViewCourseRecordList[i].name;
      courseItems.add(
        DropdownMenuItem(
          child: Container(
              width: 316,
              child: CourseBoxName(coursesRecord: listViewCourseRecordList[i],)),
          value: value,
        ),
      );
    }
    // 校验selected值是否在选项中,不在则重置为null
    List valueList = courseItems.map((e) => e.value).toList();
    if(selected != null && !valueList.contains(selected)){
      selected = null;
    }
    return Container(
      width: MediaQuery.of(context).size.width,
      height: 100,
      child: DropdownButtonHideUnderline(
        child: ButtonTheme(
          alignedDropdown: true,
          child: DropdownButton(
            value: selected,
            isDense: true,
            items: courseItems,
            hint: Text(
              "Выберите курс",
            ),
            onChanged: (newValue) {
              setState(() {
                selected = newValue;
                widget.courseSelected(newValue);
              });
            },
            isExpanded: false,
          ),
        ),
      ),
    );
  },
);
额外注意事项
  • 如果你的课程存在重名情况,不要用课程名称作为value,可以改用Firebase文档ID等唯一标识作为DropdownMenuItem的value,避免重复
  • 如果使用null作为初始值,要确保Dart SDK版本开启了空安全适配,或者显式声明DropdownButton的泛型为可空类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:54:03