Flutter:StreamBuilder 不显示 connection.state.active 上的数据

Flutter: StreamBuilder does not show data on connection.state.active

整个周末我都在努力解决这个问题,所以我最终决定征求你的意见。

有一个 streambuilder 可以侦听流或食谱(按类别过滤 -> 汤、甜点等)。

我很困惑,因为文本“Nothing”(最后一个 return 语句)是唯一显示的内容,即使我在 if 条件下的打印语句要求 connectionstate.active 显示了我所有值。

当我在文本小部件“Nothing”上方的一行打印连接状态时,我得到“active”。

当然我可以去掉我的 if 语句并将 returning 小部件放在末尾,但我想知道并理解,为什么我的 return 语句在我的 .活动状态不显示列等。即使打印语句显示在控制台中。

顺便说一句,我看到很多其他资源都使用了 Listview,但我不确定是否可以将 Listview 与堆栈一起使用(因为我想在彼此之上显示数据)。

期待您的回复!

问候 托马斯

new StreamBuilder<QuerySnapshot>(
                    stream: FirebaseFirestore.instance.collection("rezepte").where("kategorie", isEqualTo: ausgewaehlteKategorie).snapshots(),
                    builder: (context, AsyncSnapshot<QuerySnapshot> snapshot){
                      print("***** STREAMBUILDER *****");
                      if (snapshot.connectionState == ConnectionState.waiting) {
                        print(snapshot.connectionState);
                        return CircularProgressIndicator();
                      }
                      
                      if(snapshot.connectionState == ConnectionState.active){
                        print(snapshot.connectionState);
                        print(snapshot.data!.docs);
                        print(snapshot.data!.docs[0]["name"]);
                        print(snapshot.data!.docs[0]["kategorie"]);

                        print(snapshot.data!.docs.length);

                        snapshot.data!.docs.map((docs){
                          print("Test1");
                          listeAllerRezepte.add(
                            Rezept(
                              name: docs["name"].toString(),
                              kategorie: docs["kategorie"].toString(),
                              naehrwertKohlenhydrate: docs["naehrwertKohlenhydrate"],
                              naehrwertFett: docs["naehrwertFett"],
                              naehrwertEiweiss: docs["naehrwertEiweiss"],
                              naehrwertKohlenhydrateProzent: double.parse((100 / (docs["naehrwertKohlenhydrate"] + docs["naehrwertFett"] + docs["naehrwertEiweiss"]) * docs["naehrwertKohlenhydrate"]).toStringAsFixed(2)),
                              naehrwertFettProzent: double.parse((100 / (docs["naehrwertKohlenhydrate"] + docs["naehrwertFett"] + docs["naehrwertEiweiss"]) * docs["naehrwertFett"]).toStringAsFixed(2)),
                              naehrwertEiweissProzent: double.parse((100 / (docs["naehrwertKohlenhydrate"] + docs["naehrwertFett"] + docs["naehrwertEiweiss"]) * docs["naehrwertEiweiss"]).toStringAsFixed(2)),
                              img: docs["img"],
                              favorit: docs["favorit"]
                            )
                          );
                          print("Test2");

                          print(listeAllerRezepte[0]);
                          print(listeAllerRezepte[0].name.toString());
                          print(listeAllerRezepte[0].kategorie.toString());
                          print(listeAllerRezepte[0].img.toString());

                          return new Column(
                            children: [
                              new Stack(
                                alignment: Alignment.bottomCenter,
                                children: [
                                  new Text("Test1"),
                                  new Container(
                                    child: new GestureDetector(
                                      child: new Column(
                                        children: [
                                          new Text("TEST"),
                                          new Image(
                                            image: (docs["img"].toString().length > 0) ? NetworkImage(docs["img"].toString()) : NetworkImage(globals.listeAllerKategorien![nummerAusgewaehleKategorie].img.toString())
                                          ),
                                        ],
                                      ),
                                      onTap: () {
                                      },
                                    ),
                                  ),
                                  new Divider(height: 100.0)
                                ],
                              ),
                              new Divider(height: 15.0)
                            ]
                          );
                        }).toList();
                      }

                      if(snapshot.connectionState == ConnectionState.done){
                        print(snapshot.connectionState);
                      }
                      
                      if(!snapshot.hasData){
                        return Text("Loading");
                      }

                      return new Text("Nothing");
                    }
                  )

一旦 StreamBuilder 收到所有数据和完成信号,state 变为 done。它不在 active 中。您的支票应该是 is waitinghas data,然后是 no data

更新: 问题出在 if(snapshot.connectionState == ConnectionState.active) 块中的 return 语句中。您实际上并没有从块中返回一个小部件,因此该函数一直持续到它到达最终的 return 语句。

首先,做出这个if声明if(snaphsot.hasData)。那就看看这一段:

snapshot.data!.docs.map((docs){
  ...
  return new Column(
  ...
}

这里,你的return语句是给匿名函数传递给map方法的。 Column 未从生成器中返回。

虽然我不太确定您的需求是什么,但我相信您的某些小部件也嵌套不当。以下是我对您要做什么的最佳猜测,请相应地进行调整。 (为简洁起见,我省略了您的一些代码,只关注构建导致您出现问题的小部件。)

if(snapshot.hasData){
  return new Column(
    children: snapshot.data!.docs.map((docs){
      return new Stack(
       alignment: Alignment.bottomCenter,
       children: [
         new Text("Test1"),
         new Container(
           child: new GestureDetector(
             child: new Column(
               children: [
                 new Text("TEST"),
                 new Image(
                   image: (docs["img"].toString().length > 0) ? NetworkImage(docs["img"].toString()) : NetworkImage(globals.listeAllerKategorien![nummerAusgewaehleKategorie].img.toString())
                 ),
               ],
             ),
             onTap: () {},
           ),
         ),
         new Divider(height: 100.0)
       ],
     );
   },
 );
}

注意: ListView 肯定能够提供您所需要的,而且它是比 Column 更好的选择。它提供开箱即用的滚动功能、更好的性能和内存使用,以及一些可以在需要时提供 Divider 的方便的构造函数。我鼓励您在对这些结果感到满意后检查一下。