[英]Why do I need to wrap the list items in a Column in order to dynamically add items using a button to ListView Flutter?
在過去的一天里,我很難想出一段簡單的代碼來使用按鈕將一些項目添加到 ListView。 我想在我的應用程序中創建一個列表,只需單擊 FloatingActionButton 即可將項目添加到此列表中。
問題是當我點擊按鈕時,什么也沒發生。 但是當我 HotReloaded 應用程序時,項目神奇地出現在列表中(代碼塊 1)。
經過一番研究,我找到了一個完美的簡單解決方案。 我只是將項目包裝在Column小部件中,一切正常。 但我無法解釋為什么。 這是如何工作的? 我的初始代碼的哪一部分是錯誤的? 這與setState()
方法的工作方式有關嗎? setState()
究竟是如何工作的?
我的初始代碼:
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
List<Widget> items = [
Text('initial txt'),
];
void _incrementCounter() {
setState(() {
items.add(Text('NewText'));
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: ListView(
children: this.items,
),
width: 100,
height: 400,
alignment: Alignment.center,
)
],
),
alignment: Alignment.center,
// padding: EdgeInsets.fromLTRB(40, 10, 20, 10),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
第二個代碼:剛剛在_incrementCounter()
function 中創建了一個臨時列表,並將其分配給setState()
中的舊列表(我為什么要這樣做?)並將項目包裝在一個 Column 小部件中。
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
List<Widget> items = [
Text('initial txt'),
];
void _incrementCounter() {
List<Widget> ls_tmp = this.items;
ls_tmp.add(Text('New Text $_counter'));
setState(() {
_counter++;
this.items = ls_tmp;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: ListView(
children: [
Column(
children: this.items,
),
],
),
width: 100,
height: 400,
alignment: Alignment.center,
)
],
),
alignment: Alignment.center,
// padding: EdgeInsets.fromLTRB(40, 10, 20, 10),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
最后但並非最不重要的一點是,還有其他解決方案嗎?
它有點隱藏在文檔中,但你可以在這里找到它:
https://api.flutter.dev/flutter/widgets/ListView/ListView.html
與框架中的其他小部件一樣,此小部件期望子列表在此處傳入后不會發生變異。 有關更多詳細信息,請參閱SliverChildListDelegate.children的文檔。
在 Android Studio 中,如果 hover over children:
,那么它將顯示相同的文檔。
相反,您需要使用ListView.builder
:
child: ListView.builder(
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return items[index];
},
),
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.