0

我正在尝试将我的应用程序转换为定期使用三秒的 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();
  }
4

1 回答 1

0

问题不在于流,而在于选项卡控制器。我通过反复试验发现了这一点,并得出结论认为问题出在 DefaultTabBarController。一旦我删除了 DefaultTabController,流就没有被赋予错误的状态。一种解决方法可能是找出一种在 dispose 方法中处理控制器的方法。但是,我切换到使用底部导航栏并使用栏的索引来更改页面

于 2022-02-05T03:51:29.300 回答