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 waiting
、has 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
的方便的构造函数。我鼓励您在对这些结果感到满意后检查一下。
整个周末我都在努力解决这个问题,所以我最终决定征求你的意见。
有一个 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 waiting
、has 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
的方便的构造函数。我鼓励您在对这些结果感到满意后检查一下。