【问题标题】:Issue with retrieving elements using FutureBuilder使用 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 时,它会遍历数据库的每个成员。

任何帮助将不胜感激!

【问题讨论】:

    标签: flutter google-cloud-firestore future


    【解决方案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 ..);
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      相关资源
      最近更新 更多