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

Flutter中ListView.separated内Checkbox单选异常及选中项获取咨询

问题根源

所有Checkbox共享同一个bool value变量,只要这个变量改变,所有列表项的Checkbox状态会同步更新,导致点击一个全选的现象。

解决方案

要实现单个项独立选中,需为每个列表项维护单独的选中状态,以下是两种常用实现方式:

方式一:用List维护选中状态

适合简单场景,用与列表长度一致的布尔数组记录每个项的选中状态:

// 初始化布尔数组,默认所有项未选中
List<bool> isSelectedList = List.filled(5, false);

ListView.separated(
  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  itemBuilder: (context, index) => Container(
    height: 100,
    width: double.infinity,
    decoration: BoxDecoration(
      border: Border.all(color: Colors.grey, width: 1),
    ),
    child: ListTile(
      title: Row(
        children: [
          Text(list[index].name),
          const SizedBox(width: 10),
          Checkbox(
            value: isSelectedList[index],
            onChanged: (bool? newValue) {
              setState(() {
                isSelectedList[index] = newValue ?? false;
              });
            },
          )
        ],
      ),
    ),
  ),
  separatorBuilder: (context, index) => const SizedBox(height: 5),
  itemCount: 5,
)

方式二:给数据模型添加选中状态字段(推荐)

如果list是自定义数据模型,直接给模型加isSelected字段,数据与状态绑定更清晰:

先定义数据模型:

class YourModel {
  final String name;
  bool isSelected; // 新增选中状态字段,默认未选中

  YourModel({required this.name, this.isSelected = false});
}

再修改ListView代码:

ListView.separated(
  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  itemBuilder: (context, index) {
    final item = list[index];
    return Container(
      height: 100,
      width: double.infinity,
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey, width: 1),
      ),
      child: ListTile(
        title: Row(
          children: [
            Text(item.name),
            const SizedBox(width: 10),
            Checkbox(
              value: item.isSelected,
              onChanged: (bool? newValue) {
                setState(() {
                  item.isSelected = newValue ?? false;
                });
              },
            )
          ],
        ),
      ),
    );
  },
  separatorBuilder: (context, index) => const SizedBox(height: 5),
  itemCount: list.length,
)
获取已选中的项

根据不同实现方式,通过遍历筛选即可获取:

对应方式一的筛选逻辑

// 用集合操作简化筛选
final selectedItems = list.asMap().entries
    .where((entry) => isSelectedList[entry.key])
    .map((entry) => entry.value)
    .toList();

对应方式二的筛选逻辑

// 直接筛选模型中isSelected为true的项
final selectedItems = list.where((item) => item.isSelected).toList();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:01:12