Flutter DataTable点击单行却选中所有行的问题解决
你的问题出在两个核心错误上:
- 所有行的
selected属性都绑定了同一个变量rowSelected,导致只要这个变量变化,所有行的选中状态会同步改变 onSelectChanged的参数用错了,它的参数是bool?类型(表示当前行是否被选中),不是行索引
下面给你两种修复方案,按需选择:
方案一:单选(每次仅选中一行)
- 先修改状态变量,换成记录选中行索引的变量:
int? selectedRowIndex; // 初始为null,代表无选中行
- 调整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(), );
方案二:多选(可选中任意多行)
- 修改状态变量为集合,存储所有选中行的索引:
Set<int> selectedRowIndices = {}; // 初始为空集合
- 调整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
相关产品推荐
相关产品推荐

