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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:36:03