Flutter 如果数据流即将到来,则只能在Stream Builder中导航到另一个页面一次

Flutter 如果数据流即将到来,则只能在Stream Builder中导航到另一个页面一次,flutter,dart,stream-builder,Flutter,Dart,Stream Builder,我使用Stream builder从Esp32 BLE接收数据到我的颤振应用程序,我在我的应用程序中检测到癫痫发作,因此如果癫痫发作发生,我使用了currentValue=2的条件,并导航到另一个页面。但另一个页面会被多次调用,直到当前值=2停止出现。 如果条件满足且值“2”不断出现,我如何才能只调用一次页面 这是流生成器的代码,当前值变为2时调用此页: StreamBuilder<List<int>>(

我使用Stream builder从Esp32 BLE接收数据到我的颤振应用程序,我在我的应用程序中检测到癫痫发作,因此如果癫痫发作发生,我使用了currentValue=2的条件,并导航到另一个页面。但另一个页面会被多次调用,直到当前值=2停止出现。 如果条件满足且值“2”不断出现,我如何才能只调用一次页面

这是流生成器的代码,当前值变为2时调用此页:

StreamBuilder<List<int>>(
                                    stream: stream,
                                    initialData: lastValue,
                                    builder: (BuildContext context,
                                        AsyncSnapshot<List<int>> snapshot) {
                                      if (snapshot.hasError)
                                        return Text(
                                          'Error: ${snapshot.error}',
                                          style: TextStyle(
                                            fontFamily: 'SF Pro Display',
                                            fontSize: 19,
                                            color: const Color(0xffffffff),
                                            fontWeight: FontWeight.w500,
                                            height: 1.4736842105263157,
                                          ),
                                        );

                                      if (snapshot.connectionState ==
                                          ConnectionState.active) {
                                        //var currentValue = _dataParser(snapshot.data);
                                        var currentVal =
                                            snapshot.data.toString();
                                        int currentValue = int.parse(
                                            currentVal.substring(
                                                1, currentVal.length - 1),
                                            onError: (source) => -1); // 33
                                        print("String data $currentValue");
                                        if (currentValue == 2) {
                                          return FutureBuilder(
                                              future: Future.delayed(
                                                const Duration(seconds: 0),
                                                () async {
                                                  Seziurealert();
                                                }
                                              ),
                                              builder: (context, snapshot) {
                                                // setState(() {
                                                //   currentValue = 0;
                                                // });
                                                return Text(
                                                  'Seizure Occurred',
                                                  style: TextStyle(
                                                    fontFamily: 'SF Pro Display',
                                                    fontSize: 19,
                                                    color: const Color(0xffffffff),
                                                    fontWeight: FontWeight.w500,
                                                    height: 1.4736842105263157,
                                                  ),
                                                );
                                              });
                                        } else if (currentValue == 0) {
                                          return Text(
                                            'Device not calibrated',
                                            style: TextStyle(
                                              fontFamily: 'SF Pro Display',
                                              fontSize: 19,
                                              color: const Color(0xffffffff),
                                              fontWeight: FontWeight.w500,
                                              height: 1.4736842105263157,
                                            ),
                                          );
                                        } else if (currentValue == 1) {
                                          return Text(
                                            '$currentValue',
                                            style: TextStyle(
                                              fontFamily: 'SF Pro Display',
                                              fontSize: 19,
                                              color: const Color(0xffffffff),
                                              fontWeight: FontWeight.w500,
                                              height: 1.4736842105263157,
                                            ),
                                          );
                                        }
                                        return Text(
                                          '$currentValue',
                                          style: TextStyle(
                                            fontFamily: 'SF Pro Display',
                                            fontSize: 19,
                                            color: const Color(0xffffffff),
                                            fontWeight: FontWeight.w500,
                                            height: 1.4736842105263157,
                                          ),
                                        );
                                      } else {
                                        return Text(
                                          'Check the stream',
                                          style: TextStyle(
                                            fontFamily: 'SF Pro Display',
                                            fontSize: 19,
                                            color: const Color(0xffffffff),
                                            fontWeight: FontWeight.w500,
                                            height: 1.4736842105263157,
                                          ),
                                        );
                                      }
                                    },
                                  ),
我也尝试过使用它,但与Future Builder的情况一样:

SchedulerBinding.instance.addPostFrameCallback((_) {
                                            Navigator.pushAndRemoveUntil(
                                              context,
                                              MaterialPageRoute(
                                                builder: (context) {
                                                  return TriggeringAlert(
                                                      device:
                                                      widget.device);
                                                },
                                              ),
                                                  (route) => false,
                                            );
这是当值2出现时调用的我的页面的图像。这个页面一直显示,直到10秒计时器结束或者我按下取消按钮。但在我的情况下,即使计时器的10秒已经结束,页面也会再次调用,或者如果我按下取消按钮,在这种情况下页面也会再次调用


请帮助我如何避免这种情况,因为我是一个新手,不使用
,您可以使用
未来
。例如,您可以使用
Stream.firstWhere
来获取一个
未来的
,它将仅在满足特定谓词时完成

在您的情况下,它将类似于:

final future=stream.map((值){
最终currentVal=value.toString();
最终currentParsedVal=int.parse(
currentVal.子字符串(1,currentVal.length-1),
onError:(来源)=>-1,
);
打印(“字符串数据$currentParsedVal”);
返回电流解析dval;
}).firstWhere((值)=>value==2);

然后,您可以等待这个未来,并在
initState
中完成后导航到您想要的任何地方,例如。

但我想知道的是,一旦2出现,它就应该导航到触发屏幕,计时器开始计时。你是说我应该删除Stream Builder吗?对不起,我是新手,我无法理解你想让我做什么?是的,没错。一旦你的流中有一个2,你就会导航。我删除了流生成器,但它显示了你的代码错误,因为这个流生成器位于列小部件中
SchedulerBinding.instance.addPostFrameCallback((_) {
                                            Navigator.pushAndRemoveUntil(
                                              context,
                                              MaterialPageRoute(
                                                builder: (context) {
                                                  return TriggeringAlert(
                                                      device:
                                                      widget.device);
                                                },
                                              ),
                                                  (route) => false,
                                            );