Flutter中ListView.builder过滤后渲染错误元素问题如何解决?
问题原因
这是Flutter列表Widget复用机制导致的典型问题:ListView.builder 默认通过元素的位置匹配对应Widget进行复用,你没有给列表项LinhaItemWidget设置唯一Key,当过滤后列表数据发生变化时,Flutter无法识别到对应位置的列表项身份已经改变,只会复用之前位置的旧Widget,因此出现数据正确但渲染内容错误的问题。
修复方案
给每个列表项绑定唯一的Key,可以使用列表项中唯一不重复的codLinha字段作为Key的生成源,修改buildListView代码如下:
buildListView() { return ListView.builder( itemCount: controller.listaLinhas.length, itemBuilder: (context, i) { var item = controller.listaLinhas[i]; return LinhaItemWidget( // 新增唯一key key: Key(item.codLinha.toString()), linha: item, onChange: (bool val) { print('novo valor para o elemento ${item.codLinha} : $val'); controller.setaFavorito(i, val); }, onClick: (LinhaModel val) { if (item.sentido!.length > 1) { controller.sentidoSelecionado = null; popup(item); } else { controller.abreFormulario(item); } }, ); }, ); }
异常兼容
如果添加列表项Key后仍存在渲染异常,可以给ListView.builder也绑定与过滤状态关联的Key,过滤内容变化时Key同步变化,强制列表整体重绘:
// 控制器中新增变量存储当前过滤字符串 String filtroAtual = ''; @action filtra(String v) { filtroAtual = v; isFiltroFavorito = false; listaLinhas = listaLinhasAux .where((i) => '${i.codLinha} ${i.nomeLinha}' .toLowerCase() .contains(v.toLowerCase())) .toList() .asObservable(); } // 列表部分修改为 buildListView() { return ListView.builder( key: Key(controller.filtroAtual), itemCount: controller.listaLinhas.length, // 其余代码保持不变 ); }
内容的提问来源于stack exchange,提问作者mayconight
相关产品推荐
相关产品推荐

