使用 FutureBuilder 检索元素的问题

Posted

技术标签:

【中文标题】使用 FutureBuilder 检索元素的问题【英文标题】:Issue with retrieving elements using FutureBuilder 【发布时间】:2020-01-05 03:33:57 【问题描述】:

我是 Flutter 的新手,正在尝试在我的项目中使用 FutureBuilder。我正在尝试使用 Cloud Firestore 中的元素列表构建 ListView,因此我使用异步函数来获取数据,并使用 FutureBuilder 在加载之前给我一个占位符。不幸的是,当我检查 snapshot.connectionState == ConnectionState.done 时,视图将在列表完全填充之前加载,并且我只得到我正在寻找的元素之一。

我已尝试实施 Future.delay 以尝试为列表提供填充时间。我还尝试沿途打印(在下面的代码中标记)以查看是否所有元素都从数据库中提取(它们是)。我也尝试在 initState() 中初始化 Future,但它可能实现错误。

class PlayersFragment extends StatefulWidget 
  @override
  State<StatefulWidget> createState() 
    return PlayerFragStateChanged();
  


class PlayerFragStateChanged extends State<PlayersFragment> 

  Widget build(BuildContext context) 
    return
      ... //other items

      FutureBuilder(
        future: DataProvider().getPlayerList(),
        builder: (BuildContext context,
          AsyncSnapshot snapshot) 
             if (snapshot.connectionState == ConnectionState.done)
              return Expanded(
                child: ListView.builder(
                  itemBuilder: (context, position) 
                    return Padding(
                      padding:
                        const EdgeInsets.only(
                          left: 20, top: 14),
                       child: Row(
                        children: <Widget>[
                           Text(snapshot.data[position].firstName),
                          Text(snapshot.data[position].lastName),
                          Text(BoolDecider().decide(snapshot.
                              data[position].amta)),
              ),
             ],
            ),
           );
          ,
         itemCount: snapshot.data.length
         ));
          else 
          return Text('Waiting for data...');
         


       ... //other items

     
   



class DataProvider 
  Firestore db = firestore();

  Future<List<MockPlayer>> getPlayerList() async 
    var result = await db.collection('Users').get();

    var dataList = List<MockPlayer>();

    result.forEach((doc) async 

      debugPrint(doc.get('First name')); //Prints EVERY name in the     database (as it should)

      dataList.add(MockPlayer(
          await doc.get('First name'),
          await doc.get('Last name'),
          await doc.get('AMTA Status'),
          await doc.get('Phone number'),
          await doc.get('email'),
          await doc.get('ID')));
    );

    return dataList;
  


class BoolDecider 
  String decide(bool i) 
    if (i) 
      return 'Yes';
     else 
      return 'No';
    
  

我希望 FutureBuilder 打印多行,但是 FutureBuilder 中的 AsyncSnapshot 中的列表长度只有一个,而应该不止一个。

同样,当我执行 result.forEach 时,它会遍历数据库的每个成员。

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

问题出在您的 forEach 语句中。在您的 future.connectionState 设置为完成后,具有“异步”功能的 forEach 完成。这可以通过替换来解决:

result.forEach((doc) async 
      dataList.add(MockPlayer(
          await .. await .. await ..);
    );

与:

await Future.forEach(result, (doc) async 
      dataList.add(MockPlayer(
          await .. await .. await ..);
);

另外,根据 Pedantic Dart,您不应该忘记检查: snapshot.hasData &amp;&amp; !snapshot.hasError.

【讨论】:

你是救生员。谢谢!完美运行。【参考方案2】:

另一种有效的方法是替换

result.forEach((doc) async 
      dataList.add(MockPlayer(
          await .. await .. await ..);
    );

for(final doc in result) async 
      dataList.add(MockPlayer(
          await .. await .. await ..);
    );

【讨论】:

以上是关于使用 FutureBuilder 检索元素的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 FutureBuilder 和 Provider 在 Flutter 中出现错误状态没有元素

我如何在 FutureBuilder Widget 的构建器函数中等待 - Flutter

FutureBuilder : 方法 '&' 在 null 上被调用

选择值时出现颤振下拉按钮错误[使用来自 api 和 FutureBuilder 的数据]

如何在 FutureBuilder() 中正确“刷新”小部件

Flutter 将 FutureBuilder 小部件放在一个 Column 中