flutter Futurebuilder不使用future值进行更新,因为它可能在数据准备就绪之前进行初始化

siv3szwd  于 2023-05-08  发布在  Flutter
关注(0)|答案(1)|浏览(155)

截至目前,我的futurebuilder永远不会构建,它将留在“加载”中。国家永远如果我热重新加载,或改变一些东西,一旦应用程序加载它确实加载在这一点上虽然。现在我有它自动重装后1000毫秒,虽然它的坏代码。流构建器用于基于用户的位置来构建卡片列表。有问题的列表- listNearby -是在流构建器中创建的,它会给予我一个最近的8个位置列表的快照,这是我知道如何从geoflutterfire 2响应中收集的唯一方法。
这是小部件构建(Streambuilder和Futurebuilder)中的代码片段:

Widget build(BuildContext context) {
    Stream<List<DocumentSnapshot>> stream =
geo.collection(collectionRef: ref).within(center: center, radius: radius, field: field);

return Scaffold(
  body: StreamBuilder<List<DocumentSnapshot>>(
                      stream: stream,
                      builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
                        if (snapshot.data != null) {
                          List<DocumentSnapshot<Object?>>? streamList = snapshot.data?.toList();
                          for (var i = 0; i < 8; i++) {
                            var tester = streamList![i].id;
                            courtTest.add(tester);
                            listNearby = List<String>.from(courtTest);
                            Future.delayed(Duration.zero, () async {
                              listNearby = List<String>.from(courtTest);
                            });
                          }
                          return SizedBox(
                            height: 140,
                            child: ListView.separated(
                                scrollDirection: Axis.horizontal,
                                itemCount: 8,
                                separatorBuilder: (context, index) {
                                  return const SizedBox(width: 15);
                                },
                                itemBuilder: (context, index) {
                                  ///additional itembuilder stuff
                                  return ///some user interface;
                                }),
                          );
                      }),
                  FutureBuilder(
                    future: getFuture,
                    builder: (_, snapshot) {
                      if (snapshot.data != null) {
                        return Container(
                          height: 140,
                          child: ListView.separated(
                              scrollDirection: Axis.horizontal,
                              itemCount: snapshot.data.length,
                              separatorBuilder: (context, index) {
                                return const SizedBox(width: 15);
                              },
                              itemBuilder: (context, index) {
                                return buildUpcomingCard(
                                  ///card data
                                );
                              }),
                        );
                      } else {
                        Future.delayed(const Duration(milliseconds: 1000), () {
                          setState(() {
                            getFuture = getSearch();
                          });
                        });

                        return const Text('Loading...');
                      }
                    },
                  ),

基于其他研究,这可能是初始化future的正确方法,尽管因为它依赖于future值(来自Streambuilder的listNearby),下面是我认为正在发生的事情。getSearch被初始化,它看到'listNearby'没有初始化/还没有0索引,所以它默认为Futurebuilder / .hasNoData并保持在那里。
--->下面是从原始帖子更新的
提供我的getSearch future函数(这似乎是问题的原因),通过检查连接状态,我可以看到它显示connectionStatus.done,而它仍然在循环if(listNearby.isEmpty),尽管我希望它在返回值之前不应该显示连接完成-一直在我的代码结束时。

getSearch() async {
  var listNearbyNew = [];
  print('do we go here?');
  if (listNearby.isEmpty) {
    await Future.delayed(const Duration(milliseconds: 10), () {
      print('how about here?');
      getSearchFuture = getSearch();
    });
  } else {
    print('did we make it to the else?');
    var firestore = FirebaseFirestore.instance;
    for (var i = 0; i < 8; i++) {
      DocumentSnapshot gG = await firestore.collection('xxxx').doc(listNearby[i]).get();
      listTest.add(gG.data().toString());
      try {
        for (var x = 0; x < 3; x++) {
          final incremDt = _now.add(Duration(days: x));
          final incremDtFrmtd = DateFormat('MM-dd-yyyy').format(incremDt);
          var regexp = RegExp(r"(?<=host-).+?(?=:)");
          Iterable<Match> matches = regexp.allMatches(gG.get(incremDtFrmtd).toString(), 0);
          if (matches.isNotEmpty) {
            for (final Match h in matches) {
              String match2 = h[0]!; //hostEmail
              var info = gG.get(incremDtFrmtd)['xxx-$match2']; // this returns the info
              var xxx = info['xxx'];
              List xx = info['xxx'];
              List xx = info['xx'];
              List xxx = info['xxx'];
              listNearbyNew.add({
                ///add list items
              });
            }
          }
        }
      } catch (e) {
        // print(e);
      }
    }
    listNearbyNew.sort((a, b) {
      int dateComp = a['date'].compareTo!(b['date']);
      if (dateComp == 0) {
        return parseTime(a['time'][0]).compareTo(parseTime((b['time'][0])));
      }
      return dateComp;
    });
    print('done');
    return listNearbyNew;
  }
}
xxe27gdn

xxe27gdn1#

这一点:

Stream<List<DocumentSnapshot>> stream =
  geo.collection(collectionRef: ref).within(center: center, radius: 
    radius, field: field);

您正在构建中创建流。每次小部件重建时(可能是每秒60到120次,特别是如果有动画),流将 * 重新启动 *。这意味着你将永远加载,并迅速通过你的firebase免费层燃烧。(哎哟!)
解决方案是将该流提升到该小部件的initState中,或者使用类似RiverpodStreamProvider的东西来 Package 值,以便它只创建一次,然后在多个构建过程中访问。我有一个视频可以更好地说明https://youtu.be/sqE-J8YJnpg的问题。

相关问题