Flutter ListView not updating
Asked Answered
S

4

8

I wanted to create a ListView in Flutter that update when new data arrives. I am using a RefreshIndicator that triggers the list loading for testing. For my list I am using a ListBuilder to map my objects to view objects.

From what I understand, the setState() should trigger an update to my list, however it does not.

Debugging showed that my _listContent is actually filled with 72 items after when the setState() callback is called. Why does my list not auto update? Am I missing something?

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    List<Manga> _listContent = new List<Manga>();

    void _addMangas(List<Manga> mangas) {
      setState(() {
        _listContent.addAll(mangas);
        print('Cleared list');
        });
    }

    Future<Null> _onRefresh() {
      Completer<Null> completer = new Completer<Null>();

      loadMangaItems().then((mangas) => _addMangas(mangas));
      completer.complete();

      return completer.future;
    }

    return new Scaffold(
      appBar: new AppBar(

        title: new Text(widget.title),
      ),
      body: new RefreshIndicator(
          child: new ListView.builder(
              itemCount: _listContent.length,
              itemBuilder: (BuildContext ctx, int index) {
                Manga manga = _listContent[index];
                return new MangaItem(
                  name: manga.writtenName,
                  number: manga.currentNr,
                  state: false,
                );
              }),
          onRefresh: _onRefresh),
       );
    }
}
Strabismus answered 12/8, 2017 at 9:40 Comment(1)
I have a question about this implementation of the RefreshCallback (_onRefresh()). Isn't completer.complete(); being called here before the loadMangaItems() completes?Graphics
S
10

Turns out the problem was that

List<Manga> _listContent = new List<Manga>();

was defined on top of widget.build and not on top of the State class. Defining it like this works fine:

class _MyHomePageState extends State<MyHomePage> {
  List<Manga> _listContent = new List<Manga>();

  @override
  Widget build(BuildContext context) {
    ...
  }
Strabismus answered 12/8, 2017 at 10:1 Comment(1)
You can also move _addMangas and _onRefresh outside of your build method. There is no reason to have it in there.Neoplasm
G
1

I solved a similiar issue by calling the setState method (notify the framework that the internal state of this object has changed).

Example here: https://googleflutter.com/flutter-add-item-to-listview-dynamically/

Godhood answered 4/1, 2021 at 19:45 Comment(0)
F
1

I think who reading this answer try to update all list of ListView lump sum, by replace old list with new one, the problem happen if old list similar to new one in most values, I solved this problem temporarily in the following way:

setState(() => _currentList.clear());
Future.delayed(const Duration(milliseconds: 50), () {
  setState(() => _currentList.addAll(_newList));
});

You can show CircularProgressIndicator during the 50 milliseconds.

Note: if elements of current list are not the same as the elements of the new list and its has completely different, you will not face this problem.

Fiddlededee answered 15/12, 2022 at 16:30 Comment(0)
D
0

You can use the key for your custom widget, like the following:

itemBuilder: (BuildContext ctx, int index) {
  Manga manga = _listContent[index];
  return new MangaItem(
    name: manga.writtenName,
    number: manga.currentNr,
    state: false,
    key: Key(index.toString())
  );
}),
Downwards answered 5/8, 2022 at 8:38 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Tenishatenn

© 2022 - 2024 — McMap. All rights reserved.