我的目标是能够添加“假”'按下浮动操作按钮时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不会更新。我认为我缺少/误解了一个基本概念。
答案 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确实有效,但如果您开始使用更复杂的小部件(特别是有状态小部件),很可能不会。