如何更新ListView的孩子?

时间:2018-04-05 15:38:50

标签: dart flutter

我的目标是能够添加“假”'按下浮动操作按钮时ListView到ListView。

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

当我按下浮动操作按钮时,新的ListTile会添加到列表中,但ListView不会更新。我认为我缺少/误解了一个基本概念。

1 个答案:

答案 0 :(得分:1)

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

因为你传递了完全相同的列表,并且喜欢以优化的方式做事情,所以只检查ListView的子列表是否是完全相同的列表 - 并且因为你每次都传入相同的列表,它看不出差异。

一个选项是,您每次只需重新创建一个新列表(通过将notes包裹在new List.from(notes, growable: false)中。但这种错过了这一点。

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

所以看起来像这样:

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确实有效,但如果您开始使用更复杂的小部件(特别是有状态小部件),很可能不会。