我正在尝试将我的应用程序转换为定期使用三秒的 streamBuilder。但是,我现在得到的结果是错误。错误状态:Stream 已被收听。请注意,我在屏幕上使用两个列表视图来显示活动和非活动作业。这是从请求到流的代码。
List<Ticket> sortedListAwaiting = [];
List<Ticket> sortedListActive = [];
Future<List<Ticket>> getAssignedAwaitingTickets() async {
client.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
HttpClientRequest request =
await client.getUrl(Uri.parse("$emulatorHost/Jobs"));
request.headers.add("Authorization", "Bearer " + jwt);
HttpClientResponse result = await request.close();
if (result.statusCode == 200) {
List<dynamic> jsonData =
jsonDecode(await result.transform(utf8.decoder).join());
if (sortedListAwaiting.isNotEmpty) {
sortedListAwaiting.clear();
for (var i in jsonData) {
if (i['status'] == "Ready-To-Start" &&
i['staffName'] == name.toLowerCase()) {
sortedListAwaiting.add(new Ticket(
i['jobID'],
i['staffName'],
i['clientName'],
i['jobName'],
i['jobAddress'],
i['clientContact'],
i['jobDescription'],
i['jobDate'],
i['jobTime'],
i['status'],
i['isEditing'],
));
}
}
} else {
for (var i in jsonData) {
if (i['status'] == "Ready-To-Start" &&
i['staffName'] == name.toLowerCase()) {
sortedListAwaiting.add(
new Ticket(
i['jobID'],
i['staffName'],
i['clientName'],
i['jobName'],
i['jobAddress'],
i['clientContact'],
i['jobDescription'],
i['jobDate'],
i['jobTime'],
i['status'],
i['isEditing'],
),
);
}
}
}
}
return sortedListAwaiting;
}
Stream<List<Ticket>> getSortedListAwaiting() =>
Stream.periodic(Duration(seconds: 3))
.asyncMap((event) => getAssignedAwaitingTickets());
Future<List<Ticket>> getAssignedActiveTickets() async {
client.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
HttpClientRequest request =
await client.getUrl(Uri.parse("$emulatorHost/Jobs"));
request.headers.add("Authorization", "Bearer " + jwt);
HttpClientResponse result = await request.close();
if (result.statusCode == 200) {
List<dynamic> jsonData =
jsonDecode(await result.transform(utf8.decoder).join());
if (sortedListActive.isNotEmpty) {
sortedListActive.clear();
for (var i in jsonData) {
if (i['status'] == "In-Route" && i['staffName'] == name.toLowerCase()) {
sortedListActive.add(new Ticket(
i['jobID'],
i['staffName'],
i['clientName'],
i['jobName'],
i['jobAddress'],
i['clientContact'],
i['jobDescription'],
i['jobDate'],
i['jobTime'],
i['status'],
i['isEditing'],
));
}
}
} else {
for (var i in jsonData) {
if (i['status'] == "In-Route" && i['staffName'] == name.toLowerCase()) {
sortedListActive.add(
new Ticket(
i['jobID'],
i['staffName'],
i['clientName'],
i['jobName'],
i['jobAddress'],
i['clientContact'],
i['jobDescription'],
i['jobDate'],
i['jobTime'],
i['status'],
i['isEditing'],
),
);
}
}
}
}
return sortedListActive;
}
Stream<List<Ticket>> getSortedListActive() =>
Stream.periodic(Duration(seconds: 3))
.asyncMap((event) => getAssignedAwaitingTickets());
第一个列表视图
TabBarView(
children: [
Center(
child: Padding(
padding: EdgeInsets.only(left: 18, right: 18),
child: SingleChildScrollView(
child: Column(
children: [
Row(
children: [
Container(
margin: EdgeInsets.only(top: 10),
child: Text(
"Active",
),
),
],
),
StreamBuilder<List<Ticket>>(
stream: getSortedListActive(),
builder: (context,
AsyncSnapshot<List<Ticket>> snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return CircularProgressIndicator();
}
if (snapshot.hasData) {
return Container(
margin: EdgeInsets.only(top: 20),
height: 240,
child: ListView.builder(
itemBuilder: (context, index) {
return Padding(
padding:
const EdgeInsets.only(bottom: 16.0),
child: GestureDetector(
onTap: () async {
await getSpecificJob(
activeJobTickets[index].JobID);
await getLatLng(
sortedListActive[index]
.jobAddress);
print(
activeJobTickets[index].JobID);
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
TicketScreen(
activeJobTickets[index].JobID,
activeJobTickets[index]
.staffName,
activeJobTickets[index]
.clientName,
activeJobTickets[index]
.jobName,
activeJobTickets[index]
.jobAddress,
activeJobTickets[index]
.clientContact,
activeJobTickets[index]
.jobDescription,
activeJobTickets[index]
.jobDate,
activeJobTickets[index]
.jobTime,
activeJobTickets[index]
.status,
),
),
);
},
child: newTicketWidget(
sortedListActive[index].jobName,
sortedListActive[index]
.jobDescription,
sortedListActive[index].jobAddress,
sortedListActive[index].staffName,
sortedListActive[index].jobDate,
sortedListActive[index].jobTime,
),
),
);
},
itemCount: sortedListActive.length,
),
);
}
return CircularProgressIndicator();
}),
第二个列表视图
StreamBuilder<List<Ticket>>(
stream: getSortedListAwaiting(),
builder:
(context, AsyncSnapshot<List<Ticket>> snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return CircularProgressIndicator();
}
if (snapshot.hasData) {
return Container(
margin: EdgeInsets.only(top: 20),
height: 240,
child: ListView.builder(
itemBuilder: (context, index) {
return Padding(
padding:
const EdgeInsets.only(bottom: 16.0),
child: GestureDetector(
onTap: () async {
getSpecificJob(
awaitingJobTickets[index].JobID);
await getLatLng(
sortedListAwaiting[index]
.jobAddress);
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => TicketScreen(
sortedListAwaiting[index].JobID,
sortedListAwaiting[index]
.staffName,
sortedListAwaiting[index]
.clientName,
sortedListAwaiting[index]
.jobName,
sortedListAwaiting[index]
.jobAddress,
sortedListAwaiting[index]
.clientContact,
sortedListAwaiting[index]
.jobDescription,
sortedListAwaiting[index]
.jobDate,
sortedListAwaiting[index]
.jobTime,
sortedListAwaiting[index]
.status),
));
},
child: newTicketWidget(
sortedListAwaiting[index].jobName,
sortedListAwaiting[index]
.jobDescription,
sortedListAwaiting[index].jobAddress,
sortedListAwaiting[index].staffName,
sortedListAwaiting[index].jobDate,
sortedListAwaiting[index].jobTime,
),
),
);
},
itemCount: sortedListAwaiting.length,
),
);
}
return CircularProgressIndicator();
},
),
我对使用 StreamBuilder 完全陌生,我通常只单独使用 listview.builder,但现在我需要数据每三秒保持刷新一次。因此,任何指南、解释和示例都将非常感激。提前干杯开发人员。
编辑 我被告知尝试将流添加到 var 并将其设置为 innit 状态但是我仍然有错误
late Stream<List<Ticket>> myPeriodicStream;
late Stream<List<Ticket>> myPeriodicStream1;
@override
void initState() {
refreshLists();
super.initState();
myPeriodicStream = getSortedListActive();
myPeriodicStream1 = getSortedListAwaiting();
}