Flutter中List<Map>数据源的DataTable触发onSelectChanged后无法更新
问题根因
你遇到的这个问题基本是Flutter状态更新的浅比较规则、引用传递逻辑两个点没处理对导致的,常见触发原因有3种:
- 给DataTableBuilder传参时传的是
Orders.rows的拷贝副本,修改的是副本值,没有改动原全局模型的rows数据 Orders.rows初始化时用了不可变集合修饰(如const、List.unmodifiable),内部元素修改后不会同步到集合本身- setState触发重绘时,组件对rows做浅比较只校验内存地址,数组内部元素改动不会被识别为状态变化,所以DataTable不会刷新
修复方案
- 第一步:确保你修改的是原模型的rows元素,不要做额外的集合拷贝。禁止出现
var tempRows = List.from(Orders.rows)这种拷贝后改tempRows的逻辑,直接修改Orders.rows[index].Checked的值 - 第二步:修改完单个元素后刷新rows的内存地址,适配Flutter浅比较逻辑。改完值后新增一行
Orders.rows = List.from(Orders.rows),生成新的数组实例触发状态变更识别 - 第三步:确认封装的
DataTableBuilder组件没有加const修饰,且内部没有对传入的rows做本地缓存,完全依赖外部传入的rows参数渲染表格 - 第四步:把修改逻辑放在setState的作用域内,示例代码如下:
onSelectChanged: (bool? checkedValue) { if (checkedValue == null) return; setState(() { // 直接修改原模型对应行的选中状态 Orders.rows[index].Checked = checkedValue; // 生成新的数组引用,触发浅比较更新 Orders.rows = List.from(Orders.rows); }); }
如果上述步骤完成后还不刷新,可以给DataTableBuilder绑定唯一值的Key,强制数据源变化时组件重建:
DataTableBuilder( // 用rows的哈希值作为Key,只要rows内容变化就会生成新Key触发重建 key: ValueKey(Orders.rows.hashCode), rows: Orders.rows, // 其他配置参数 )
内容的提问来源于stack exchange,提问作者Stephen Venter
相关产品推荐
相关产品推荐

