如何在 Flutter 中构建动态列表?
Posted
技术标签:
【中文标题】如何在 Flutter 中构建动态列表?【英文标题】:How to build a dynamic list in Flutter? 【发布时间】:2018-05-29 08:02:45 【问题描述】:我将此小部件附加到 Scaffold
正文。小部件获得一个返回 json 对象的 async
方法。
我想从该 json 对象动态构建一个列表。问题是屏幕是空的。由于某种原因,当列表准备好或类似的东西时,这个小部件需要刷新自己。
有什么想法吗?
class TestList extends StatelessWidget
final quiz;
TestList(this.quiz);
@override
Widget build(BuildContext context)
var listArray = [];
this.quiz.then((List value) // this is a json object
// loop through the json object
for (var i = 0; i < value.length; i++)
// add the ListTile to an array
listArray.add(new ListTile(title: new Text(value[i].name));
);
return new Container(
child: new ListView(
children: listArray // add the list here.
));
【问题讨论】:
【参考方案1】:您可以使用setState
重新构建用户界面。
例子:
class TestList extends StatefulWidget
final Future<List> quiz;
TestList(this.quiz);
@override
_TestListState createState() => new _TestListState();
class _TestListState extends State<TestList>
bool loading = true;
_TestListState()
widget.quiz.then((List value)
// loop through the json object
for (var i = 0; i < value.length; i++)
// add the ListTile to an array
listArray.add(new ListTile(title: new Text(value[i].name));
//use setState to refresh UI
setState(()
loading = false;
);
);
@override
Widget build(BuildContext context)
List<Widget> listArray = [];
return new Container(
child: new ListView(
children: loading?[]:listArray // when the state of loading changes from true to false, it'll force this widget to reload
));
【讨论】:
setState() isn't defined for the class TestList
嗯
将您的 TestList 设为 StatefulWidget。等一下,我将编辑我的答案以实现 StatefulWidget。
我认为setState(() loading = false; );
可能需要设置在循环之外
是的,虽然有些奇怪。如果我注释掉setState()
,loading
在widget.quiz.then..
中是错误的,除非我将bool loading = true;
移到它上面。
和 setState(() loading = false; );
内的 widget.quiz.then..
出于某种原因进行了无限循环。也许一些范围问题..【参考方案2】:
您可以使用 FutureBuilder 来帮助处理小部件状态:
new FutureBuilder<List>(
future: widget.quiz,
builder:
(BuildContext context, AsyncSnapshot<List> snapshot)
switch (snapshot.connectionState)
case ConnectionState.none:
return new Text('Waiting to start');
case ConnectionState.waiting:
return new Text('Loading...');
default:
if (snapshot.hasError)
return new Text('Error: $snapshot.error');
else
return new ListView.builder(
itemBuilder: (context, index) =>
new Text(snapshot.data[index].name),
itemCount: snapshot.data.length);
,
)
基本上,它会根据未来状态通知 builder 上指定的方法。一旦 future 收到一个值并且没有错误,您可以使用 ListView.builder 来制作列表,这是在所有项目都属于同一类型时创建列表的便捷方法。
更多信息https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html
【讨论】:
虽然你的回答更符合 Async 标准,但我不知道为什么我收到了多次调用和 snapshot.hasError 被执行,ListBuilder 从未被执行以上是关于如何在 Flutter 中构建动态列表?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter/Firestore - 在流构建器中的动态列表视图上实现“分页”