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

Flutter DataTable点击单行却选中所有行的问题解决

你的问题出在两个核心错误上:

  • 所有行的selected属性都绑定了同一个变量rowSelected,导致只要这个变量变化,所有行的选中状态会同步改变
  • onSelectChanged的参数用错了,它的参数是bool?类型(表示当前行是否被选中),不是行索引

下面给你两种修复方案,按需选择:


方案一:单选(每次仅选中一行)

  1. 先修改状态变量,换成记录选中行索引的变量:
int? selectedRowIndex; // 初始为null,代表无选中行
  1. 调整DataTable的关键代码:
DataTable(
  columns: const <DataColumn>[
    DataColumn(label: Text('ID')),
    DataColumn(label: Text('Visitor\'s Name')),
    DataColumn(label: Text('Visit Date')),
    DataColumn(label: Text('Time In')),
    DataColumn(label: Text('Time Out')),
    DataColumn(label: Text('Department')),
    DataColumn(label: Text('Visitee')),
    DataColumn(label: Text('Address')),
    DataColumn(label: Text('Phone')),
    DataColumn(label: Text('Purpose of Visit')),
  ],
  rows: List.generate(snapshot.data!.length, (index) {
    var data = snapshot.data![index];
    return DataRow(
        // 仅当前行索引等于选中索引时,才标记为选中
        selected: selectedRowIndex == index,
        // 修正参数名,isSelected是当前行的选中状态
        onSelectChanged: (isSelected) {
          setState(() {
            // 单选逻辑:点击已选中行则取消,否则选中当前行
            selectedRowIndex = isSelected! ? index : null;
            // 若希望点击已选中行保持选中,直接写 selectedRowIndex = index;
          });
        },
        cells: [
          DataCell(Text(data.id.toString())),
          DataCell(Text(data.visitor_name.toString())),
          DataCell(Text(data.visit_date.toString())),
          DataCell(Text(data.Time_in.toString())),
          DataCell(TextFormField(initialValue: data.Time_out.toString())),
          DataCell(Text(data.Department.toString())),
          DataCell(Text(data.Visitee_name.toString())),
          DataCell(Text(data.Address.toString())),
          DataCell(Text(data.Phone.toString())),
          DataCell(Text(data.Purpose_of_visit.toString())),
        ]);
  }).toList(),
);

方案二:多选(可选中任意多行)

  1. 修改状态变量为集合,存储所有选中行的索引:
Set<int> selectedRowIndices = {}; // 初始为空集合
  1. 调整DataTable代码:
DataTable(
  columns: const <DataColumn>[
    // 列定义保持不变
    DataColumn(label: Text('ID')),
    DataColumn(label: Text('Visitor\'s Name')),
    // ... 其他列
  ],
  rows: List.generate(snapshot.data!.length, (index) {
    var data = snapshot.data![index];
    return DataRow(
        // 判断当前行索引是否在选中集合内
        selected: selectedRowIndices.contains(index),
        onSelectChanged: (isSelected) {
          setState(() {
            if (isSelected!) {
              selectedRowIndices.add(index);
            } else {
              selectedRowIndices.remove(index);
            }
          });
        },
        cells: [
          // 单元格内容保持不变
          DataCell(Text(data.id.toString())),
          // ... 其他单元格
        ]);
  }).toList(),
);

核心修正逻辑:

  • 每个行的selected属性现在只和自身索引绑定,不再共用全局变量,确保只有目标行改变选中状态
  • 修正onSelectChanged的参数使用,正确处理选中/取消选中的状态切换

内容的提问来源于stack exchange,提问作者Jonathan Kwabena Ewenam Kudiab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:17:02