一个如何更新ListView的子级? [英] How does one update ListView's children?

查看:94
本文介绍了一个如何更新ListView的子级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是能够在按下浮动操作按钮时将虚拟 ListTiles添加到ListView。

My goal is to be able to add 'dummy' ListTiles to a ListView when pressing a Floating Action Button.

class Notes extends StatefulWidget{

  _NotesState createState() => new _NotesState();
}

class _NotesState extends State<Notes>{

  List<ListTile> notes =[];

  void addNewNote(){
     setState((){
        notes.add(new ListTile(title: new Text("Broccolli")));
  }

  @override
  Widget build(BuildContext context){
     return new Scaffold(
       appBar: new AppBar(title: "NOTES"),
       body: new Stack(
       children: <Widget>[
        // The notes
        new Container(
          child: new ListView(
            children: notes,
          )
        ),
        // The add notes button
        new FloatingActionButton(
          tooltip: 'Add a note',
          onPressed: addNewNote, 
        )
       ],
      ),
     );
  }
}

当我按下Floating Action Button时,新的ListTile被添加到列表中,但是ListView没有得到更新。我想我缺少/错过了一个基本概念。

When I press the Floating Action Button the new ListTile gets added to the list, but the ListView does not get updated. I presume I am missing/missunderstanding a basic concept.

推荐答案

最大的问题是您直接将小部件列表作为Notes的子级传递。当Flutter进行重建时,它会查看所有小部件并检查它们是否已更改;

The biggest issue is that you're passing a list of widgets directly as the children of Notes. When Flutter does a rebuild, it looks at all the widgets and checks to see if they've changed; it then only propagates changes town branches that have changed.

因为您要传递完全相同的列表,并且喜欢以一种优化的方式执行操作,所以仅检查是否ListView的子级列表是完全相同的列表-由于每次都传递相同的列表,因此看不到差异。

Because you're passing the exact same list and flutter likes to do things in an optimized way, it's only checking if the ListView's children list is the exact same list - and because you're passing in the same list each time, it doesn't see the difference.

一个选项是您可以每次简单地重新创建一个新列表(通过在 new List中包装 notes 。from(notes,可增长:false)

One option is that you could simply recreate a new list each time (by wrapping notes in new List.from(notes, growable: false). But that sort of misses the point.

您的窗口小部件应该只存储创建窗口小部件所需的信息,然后才应在窗口小部件中实际创建窗口小部件。 build 函数。

Your widget should only be storing the information needed to create widgets, and then the actual creation of widgets should be done in the build function.

所以看起来像这样:

class Notes extends StatefulWidget {
  _NotesState createState() => new _NotesState();
}

class _NotesState extends State<Notes> {
  List<String> notes = [];

  void addNewNote() {
    setState(() {
      notes.add("Broccolli ${notes.length}");
    });
  }

  @override
  Widget build(BuildContext context) {
    print("Notes: $notes");
    return new Scaffold(
      appBar: new AppBar(title: new Text("NOTES")),
      body: new Stack(
        children: <Widget>[
          // The notes
          new Container(
            child: new ListView(
                children: notes
                    .map((string) => new ListTile(title: new Text(string)))
                    .toList(growable: false)),
          ),
          // The add notes button
          new FloatingActionButton(
            tooltip: 'Add a note',
            onPressed: addNewNote,
          )
        ],
      ),
    );
  }
}

直接存储listTiles确实可以,但是很有可能如果您开始拥有更复杂的小部件(特别是有状态的小部件)则不会。

Storing the listTiles directly does work, but it quite likely wouldn't if you started to have more complex widgets (in particular stateful widgets).

这篇关于一个如何更新ListView的子级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆