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

Flutter ListView中DropdownButton选中值绑定RangeError问题咨询

错误原因

RangeError的触发逻辑非常明确:

  1. 你初始化的_selectedItem是空数组,初始状态下fileList长度为0,ListView的itemCount被设置为1,渲染第0个item时直接执行_selectedItem[index]访问空数组的0号索引,直接越界。
  2. 后续用户选择文件后,你没有同步维护_selectedItem的长度和fileList对齐,只要文件数量和选中值列表长度不一致,访问对应索引就会报错。
修复方案

核心规则

保证_selectedItem的长度永远和fileList长度完全一致,每个文件对应一个选中值存储位,初始值为空字符串;空文件状态下不要渲染DropdownButton组件,单独做上传占位UI。

具体实现

  • 同步维护两个列表的长度:所有对fileList的新增、删除操作,都要同步对_selectedItem做同位置的增删
    // 用户选中新文件后的回调
    void handlePickFiles(List<File> newFiles) {
      setState(() {
        fileList.addAll(newFiles);
        // 新增对应数量的空值占位
        _selectedItem.addAll(List.filled(newFiles.length, ''));
      });
    }
    
    // 用户删除指定位置文件的逻辑
    void handleDeleteFile(int index) {
      setState(() {
        fileList.removeAt(index);
        // 同步删除对应位置的选中值
        _selectedItem.removeAt(index);
      });
    }
    
  • 调整ListView渲染逻辑,空状态单独处理
    ListView.separated(
      itemCount: fileList.isEmpty ? 1 : fileList.length,
      separatorBuilder: (BuildContext context, int index) {
        return SizedBox(height: 8.h);
      },
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      itemBuilder: (context, index) {
        // 空状态渲染上传占位,不加载下拉框
        if (fileList.isEmpty) {
          return GestureDetector(
            onTap: () {/* 触发文件选择逻辑 */},
            child: Container(
              height: 120.h,
              decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
              child: const Center(child: Text('点击选择要上传的文件')),
            ),
          );
        }
    
        // 有文件时渲染对应卡片
        return Container(
          padding: EdgeInsets.all(12.w),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 文件名模块
              Text(fileList[index].name, maxLines: 1, overflow: TextOverflow.ellipsis),
              SizedBox(height: 8.h),
              // 文件类型下拉框
              DropdownButton(
                hint: const Text('Select type'),
                isExpanded: true,
                underline: Container(),
                value: _selectedItem[index].isNotEmpty ? _selectedItem[index] : null,
                items: _itemList.map((e) {
                  return DropdownMenuItem(
                    child: Text(e.description!),
                    value: e.code,
                  );
                }).toList(),
                onChanged: (value) {
                  setState(() {
                    _selectedItem[index] = value.toString();
                  });
                }
              ),
              SizedBox(height: 8.h),
              // 备注项模块
              const TextField(
                decoration: InputDecoration(
                  hintText: '请输入备注',
                  border: OutlineInputBorder(),
                ),
              )
            ],
          ),
        );
      },
    )
    

只要保证两个列表长度完全同步,Dropdown的索引访问就不会出现越界问题,选中值也能正常绑定展示。

内容的提问来源于stack exchange,提问作者M.A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:36:34