如何在 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()loadingwidget.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 - 在流构建器中的动态列表视图上实现“分页”

如何在 Flutter 中动态更新列表中元素的样式?

Flutter - 动态构建小部件

如何在动态列表视图中导航至下一页-Flutter

Flutter:添加动态 TextFormField 以将数据上传到列表

Flutter:使用 Firebase 动态链接,有人可以告诉我如何通过链接传递参数列表以及如何接收它吗?