Flake
Flake

Reputation: 1406

flutter is updating without using setState

In the example provided here for infinite scrolling, it adds 10 more items when it reaches the end.

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

What I don't understand is how does the ListView get updated even when they are not calling setState()?

Upvotes: 2

Views: 1303

Answers (1)

Edman
Edman

Reputation: 5605

Well noted. We will need a little more of the code to understand this.

  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]);
      },
    );
  }

Looking at the docs for ListView and SliverChildBuilderDelegate I see the statement:

builder will be called only for indices greater than or equal to zero and less than childCount (if childCount is non-null).

So what's happening is we're not providing an itemCount to the ListView, and this makes it believe it has infinite elements. So we don't need to setState to tell it that we have 10 more items; it never knew how many items we had to begin with. As long as the items are there when the ListView get to them it will be happy.

Strictly speaking this list does not "track" changes to _suggestions. By giving a null itemCount you're telling ListView that you have infinite items; besides, the existing items in _suggestions never change, they're just appended. In this example flutter only needs to be told of changes to _saved.

On the other hand if we had something like ListView.builder(itemCount: _suggestions.length ...), then we would need to make sure we call setState when the list length changes.

Upvotes: 2

Related Questions