Flutter ListView不更新

7

我希望在Flutter中创建一个ListView,当新数据到达时更新。我正在使用RefreshIndicator来触发测试列表加载。对于我的列表,我使用ListBuilder将我的对象映射到视图对象。

据我所知,setState()应该触发对我的列表的更新,但实际上没有更新。

调试显示,当调用setState()回调时,我的_listContent实际上填充了72个项目。为什么我的列表不会自动更新?我有遗漏什么吗?

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

1
我有一个关于 RefreshCallback(_onRefresh())实现的问题。这里 completer.complete(); 不是在 loadMangaItems() 完成之前被调用了吗? - sidecarcat
4个回答

10

事实证明问题出在

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

这个函数是在widget.build的顶部而不是State类的顶部定义的。像这样定义可以正常工作:

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

  @override
  Widget build(BuildContext context) {
    ...
  }

1
你还可以将_addMangas和_onRefresh方法移到build方法之外。没有必要放在里面。 - Rainer Wittmann

1

1

我认为阅读这篇答案的人尝试通过用新列表替换旧列表来更新ListView的所有列表,如果旧列表与新列表在大多数值上相似,则会出现问题,我暂时通过以下方式解决了这个问题:

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

您可以在50毫秒内展示循环进度指示器

注意:如果当前列表的元素与新列表的元素不同且完全不同,您将不会遇到此问题。


0

您可以为自定义小部件使用键


目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接