【问题标题】:How to rebuild only a spesific item in the Listview?如何仅重建 Listview 中的特定项目?
【发布时间】:2021-08-17 18:36:40
【问题描述】:

我有一个实体对象,为简单起见,我们现在称它为Todo。我想要一个可以同时编辑多个待办事项的小部件,例如EditableTodoList(这将显示EditableTodos 的列表)。 这个小部件会收到List<Todo>Function onTodoEdited(Todo) 之类的东西。 我正在尝试使用不可变数据,因此当正在编辑EditableTodo 时(并且事件被传播到包含EditableTodoList 的小部件),我将创建一个新的List<Todo>,其中包含更新的Todo , 但随后 EditableTodoList 将重建其所有 EditableTodos 内部。

我该如何优化这一点,只重建相关的EditableTodo?我不想修改原始道具List<Todo>,因为这极大地隐藏了一个重要的细节。

背景:目前状态在一个肘内,我context.select-ing 为每个EditableTodo 列出状态对应的Todo 项目,这样只有编辑的项目重建。我想将这个EditableTodoList 与cubit 解耦。

理论上我认为这是不可能的,因为EditableTodoList 被赋予了新属性,所以它必须重建,这意味着所有子树都被重建。 EditableTodo 不能是 const,因为它的 prop 不是常量。 但是,将EditableTodoList 与腕尺分开的最优雅的方法是什么?因为它只需要一个List<Todo> 来显示,应该可以以某种方式优化未更改的Todos 的呈现

【问题讨论】:

    标签: flutter bloc


    【解决方案1】:

    您应该考虑小部件、元素和渲染树的工作方式,以便受到关注。关于 Flutter 的渲染机制,有一个很棒的 video。重建树时,仅使用 key 和运行时类型值来构建 compares 两个版本的小部件。这意味着如果您更改 Text 小部件的字符串值,将再次使用具有变异数据的相同渲染对象。不会创建新的渲染对象,这意味着渲染树上不会发生不必要的重建。与渲染树相比,重建小部件树并不昂贵。

    ListView 中最小化构建范围是有限制的。 ListView 本身应该被重建以更新项目。因此,您不能针对特定项目进行重建。但是项目可以反应性地重建自己(例如,监听流的项目可以重建而不影响其他项目)。因此,不可变集合在这种情况下并不重要,因为框架不关心值,而是关心键和运行时类型。你可以传递一个完全修改过的列表,也可以传递一个只改变一个元素的列表,效果是一样的。

    【讨论】:

    • 我明白了,但这是否意味着,只要不制作新的渲染对象,所有“重建”(调用构建方法)都可以吗?我不知道我应该为尽可能少的重建而茁壮成长。 this article 建议优化小部件树以最小化重建的子树
    • 编辑了我的答案。
    • 谢谢!我会继续尽量减少重建范围
    猜你喜欢
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    相关资源
    最近更新 更多