【问题标题】:flutter is updating without using setState颤振正在更新而不使用 setState
【发布时间】:2018-05-19 19:04:23
【问题描述】:

在为无限滚动提供here 的示例中,它会在到达末尾时再添加10 个项目。

if (index >= _suggestions.length) {
      // ...then generate 10 more and add them to the suggestions list.
      _suggestions.addAll(generateWordPairs().take(10));
}

我不明白的是,即使他们没有调用 setState(),ListView 是如何更新的?

【问题讨论】:

    标签: android dart flutter


    【解决方案1】:

    注意了。我们需要更多的代码来理解这一点。

      Widget _buildSuggestions() {
        return new ListView.builder(
          padding: const EdgeInsets.all(16.0),
          itemBuilder: (context, i) {
            if (i.isOdd) return new Divider();
    
            final index = i ~/ 2;
            if (index >= _suggestions.length) {
              _suggestions.addAll(generateWordPairs().take(10));
            }
            return _buildRow(_suggestions[index]);
          },
        );
      }
    

    查看ListView 和SliverChildBuilderDelegate 的文档,我看到了以下声明:

    builder 将仅对大于或等于零且小于 childCount 的索引调用(如果 childCount 不为空)。

    所以发生的事情是我们没有向ListView 提供itemCount,这使它相信它有无限的元素。所以我们不需要setState 告诉它我们还有10 件物品;它永远不知道我们必须从多少项目开始。只要ListView 收到物品时物品在那里,它就会很高兴。

    严格来说,此列表不会“跟踪”对_suggestions 的更改。通过给一个空的itemCount 你告诉ListView 你有无限的项目;此外,_suggestions 中的现有项目永远不会改变,它们只是被附加。在这个例子中,flutter 只需要被告知 _saved 的变化。

    另一方面,如果我们有类似的东西 ListView.builder(itemCount: _suggestions.length ...),那么我们需要确保在列表长度发生变化时调用setState。

    【讨论】:

    • 埃德曼的回答是正确的。但是,如果您尝试实现“在滚动时加载更多数据”,请不要遵循本教程。他们的例子是一种非常丑陋的做法。
    • @RémiRousselet 出于好奇,您愿意解释一下有什么不好吗?是不是他们会在列表结束时刷新列表?或者您会如何建议这样做?
    • 真的没有这样的触发器。当用户滚动ListView 告诉它的构建器给它索引i 处的项目,如果我们被要求提供一个我们没有的索引,我们会即时创建它。任何时候都不会通知列表视图有新元素。 ListView 甚至根本不知道 _suggestions。它知道它有一个itemBuilder,它将在需要时创建小部件。
    • 如果我理解正确,它只是因为新项目是同步生成的。如果获取是异步的,那么这应该不起作用。对吗?
    • 正确。如果获取是异步的,则列表视图可能会要求您提供一个您还没有的条目,在这种情况下,您需要在拥有它后通知列表视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2021-10-21
    • 2021-11-23
    • 2021-10-20
    • 2021-04-04
    • 1970-01-01
    • 2019-08-29
    相关资源
    最近更新 更多