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

Flutter条件渲染异常:仅加载对话框选中项中首个组件的问题排查

解决Flutter中仅能渲染第一个选中Widget的问题

看起来你遇到的核心问题是选中项的索引对应关系错误,加上checkIndex列表的维护不完整,导致只有第一个选中项能正确渲染。我来一步步帮你修复:

问题根源分析

  1. checkIndex维护缺失:你的onChecked方法在取消选中时,只从nonRepated中移除了名称,但没有同步删除checkIndex里对应的原始数据索引。这会导致两个列表的内容、长度不匹配,后续渲染时取到错误的数据。
  2. 索引映射错误:构建Widget时,你用nonRepated的循环索引i去访问responseData[i],但nonRepated是选中项的名称列表,它的索引和原始responseData的索引没有对应关系。比如你选中原始列表第2项时,nonRepated的索引是0,但responseData[0]并不是你选中的项。

修复步骤

1. 修正onChecked方法,同步维护checkIndex

确保取消选中时,同时从checkIndex中移除对应的原始索引:

onChecked(var value, int i, String name) {
  setState(() {
    if (responseData[i].isChecked == true) {
      checkIndex.add(i);
      nonRepated.add(responseData[i].name);
    } else {
      // 新增:同步移除checkIndex中的原始索引
      checkIndex.remove(i);
      nonRepated.remove(responseData[i].name);
    }
  });
}

2. 修正布局构建逻辑,使用正确的原始数据索引

把循环中的索引映射修正为checkIndex[i],并拆分出单独的方法让代码更清晰:

BuildLayout Widget _buildLayout(BuildContext context) {
  return Container(
    padding: const EdgeInsets.all(10),
    child: Column(
      children: <Widget>[
        // 遍历选中项,调用单独的构建方法
        for (int i = 0; i < nonRepated.length; i++)
          _buildSelectedItemWidget(i),
        SizedBox(height: 10),
        nonRepated.isNotEmpty ? _buildButton() : Container(),
      ],
    ),
  );
}

// 单独构建每个选中项的Widget
Widget _buildSelectedItemWidget(int listIndex) {
  // 获取当前选中项对应的原始数据索引
  final originalDataIndex = checkIndex[listIndex];
  final selectedName = responseData[originalDataIndex].name;
  
  if (selectedName == "गाई") {
    return Cow(nonRepated, listIndex, originalDataIndex, selectedName, onDelete);
  } else if (selectedName == "भेँडा/बाख्रा/च्याङ्ग्रा") {
    return SheepGoat(nonRepated, listIndex, originalDataIndex, selectedName, onDelete);
  } else {
    return Text(listIndex.toString());
  }
}

优化建议(可选)

为了避免维护两个列表(checkIndex和nonRepated)带来的同步问题,你可以直接存储选中的responseData对象,这样索引和数据天然对应:

// 替换原来的checkIndex和nonRepated,直接存储选中的数据对象
List<YourDataModel> selectedItems = [];

// 修改onChecked方法
onChecked(var value, int i, String name) {
  setState(() {
    final item = responseData[i];
    if (item.isChecked == true) {
      selectedItems.add(item);
    } else {
      selectedItems.remove(item);
    }
  });
}

// 重构布局构建方法
BuildLayout Widget _buildLayout(BuildContext context) {
  return Container(
    padding: const EdgeInsets.all(10),
    child: Column(
      children: <Widget>[
        for (int i = 0; i < selectedItems.length; i++)
          selectedItems[i].name == "गाई" 
              ? Cow(selectedItems, i, i, selectedItems[i].name, onDelete) 
              : selectedItems[i].name == "भेँडा/बाख्रा/च्याङ्ग्रा" 
                  ? SheepGoat(selectedItems, i, i, selectedItems[i].name, onDelete) 
                  : Text(i.toString()),
        SizedBox(height: 10),
        selectedItems.isNotEmpty ? _buildButton() : Container(),
      ],
    ),
  );
}

这样就彻底避免了索引不匹配的问题,代码也更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:48:12