我正在尝试从 firestore 中获取数据并将其显示在表格中。我首先获取未来函数中的数据,然后将未来函数转换为 Stream。当我在 streambuilder 中使用 Stream 函数时,出现错误“错误状态:Stream 已被收听”。经过一番研究,我发现广播应该可以解决问题。但这里有点棘手:由于某些原因,广播没有被接受,页面加载无休止。我做错了什么?
这里是 future 函数转换为流的地方
Stream<List<dynamic>> LinkedOtherOffersAsStream() async* {
List<dynamic> data = await getLinkedOtherOffers(); // asynchrone Future-Function
yield data; // Send data to the stream
}
这是在我的 OffersPage 中,数据应该打印出来:
final StreamController<Stream<List<dynamic>>> controller = StreamController<Stream<List<dynamic>>>.broadcast();
//This is where your "number" go in
Sink<Stream<List<dynamic>>> get inputNumber => controller.sink;
//This is where your "number" go out
Stream<Stream<List<dynamic>>> get outputNumber => controller.stream;
void initState() {
super.initState();
inputNumber.add(OfferController().LinkedOtherOffersAsStream());
}
@override
void dispose() {
controller.close();
super.dispose();
}
这是我的streambuilder:
StreamBuilder <dynamic>(
stream: outputNumber,
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (!snapshot.hasData) {
return LinearProgressIndicator();
}
return SizedBox(child:Column(children: [
ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return Card (
child: ListTile(
title: Text(snapshot.data![index]["title"],style: TextStyle(fontWeight: snapshot.data![index]["noticed"] == true ? FontWeight.normal : FontWeight.bold), ),
subtitle: Text('${snapshot.data![index]["description"].toString()}...'),
trailing: Text(snapshot.data![index]["createdAt"]),
onTap: (){ShowDialog().OffersDialogOwnOffers(context, snapshot.data![index]["title"], snapshot.data![index]["description"], snapshot.data![index], snapshot.data![index]["createdAt"],snapshot.data![index]["offerId"]);
},
),
);
}
)
]),);
},
),
也许它有助于更好地理解流问题:我有两个不同的选项卡,每个选项卡中都有一个 Streambuilder。当我在两个选项卡之间切换时,出现上述错误(错误状态:已收听流)。
感谢您的帮助:)
解决问题的另一种方法是这个,但它也没有帮助:
final broadcaststream = OfferController().LinkedOtherOffersAsStream().asBroadcastStream(
onCancel: (controller) {
print('Stream paused');
controller.cancel();
},
onListen: (controller) async {
if (controller.isPaused) {
print('Stream resumed');
controller.resume();
}
},
);