Переход на другую страницу в Stream Builder только один раз, если идет поток данных

Я использую Stream Builder для получения данных из Esp32 BLE в свое приложение Flutter, я обнаруживаю припадки в своем приложении, поэтому я использовал условие currentValue = 2, если происходит припадок, и перехожу на другую страницу. Но другая страница вызывается много раз, пока не перестанет приходить текущее значение = 2. Как я могу вызвать страницу только один раз, если условие удовлетворяет, а значение 2 продолжает поступать?

Это моя code of Stream Builder, где страница вызывается, когда текущее значение становится равным 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,
                                          ),
                                        );
                                      }
                                    },
                                  ),

Функция оповещения о приступе:

Seziurealert(){
    Navigator.pushAndRemoveUntil(
      context,
      MaterialPageRoute(
        builder: (context) {
          return TriggeringAlert(
              device:
              widget.device);
        },
      ),
          (route) => false,
    );

  }

Я также пытался использовать это, но происходило то же самое, что и с Future Builder:

SchedulerBinding.instance.addPostFrameCallback((_) {
                                            Navigator.pushAndRemoveUntil(
                                              context,
                                              MaterialPageRoute(
                                                builder: (context) {
                                                  return TriggeringAlert(
                                                      device:
                                                      widget.device);
                                                },
                                              ),
                                                  (route) => false,
                                            );

Это изображение моей страницы, которое вызывается при возникновении значения 2. Эта страница продолжает отображаться до тех пор, пока таймер не истечет 10 секунд или я не нажму кнопку отмены. Но в моем случае, даже если 10 секунд таймера истекли, страница вызывается снова ИЛИ если я нажимаю кнопку отмены, в этом случае страница также вызывается снова.

введите здесь описание изображения

Пожалуйста, помогите мне, как я могу избежать этого, поскольку я новичок во Flutter.


person Nabia Salman    schedule 01.06.2021    source источник


Ответы (1)


Вместо использования Stream вы можете использовать Future. Например, вы можете использовать Stream.firstWhere для получения Future, которое завершится только при выполнении определенного предиката.

В вашем случае это будет что-то вроде:

final future = stream.map((value) {
  final currentVal = value.toString();
  final currentParsedVal = int.parse(
    currentVal.substring(1, currentVal.length - 1),
    onError: (source) => -1,
  );
  print("String data $currentParsedVal");
  return currentParsedVal;
}).firstWhere((value) => value == 2);

Затем вы можете дождаться этого будущего и перейти туда, куда вы хотите, когда оно будет завершено, например, в вашем initState.

person Mateus Felipe    schedule 01.06.2021
comment
Но я хочу, чтобы, как только появится 2, он перешел на экран триггера, где запускается таймер. - person Nabia Salman; 01.06.2021
comment
Вы говорите, что я должен удалить Stream Builder? - person Nabia Salman; 01.06.2021
comment
Извините, я новичок во Flutter, я не могу понять, что вы хотели, чтобы я сделал вместо этого? - person Nabia Salman; 01.06.2021
comment
Да, точно. Как только в вашем потоке будет 2, вы будете перемещаться. - person Mateus Felipe; 02.06.2021
comment
я удалил построитель потоков, но он показал мне ошибку с вашим кодом, потому что этот построитель потоков находится внутри виджета столбца - person Nabia Salman; 02.06.2021
comment
Предложенный мной сниппет должен быть в другом месте, например в методе initState, а не внутри вашего метода build. - person Mateus Felipe; 02.06.2021
comment
как я могу использовать будущее для перехода на другую страницу? - person Nabia Salman; 02.06.2021
comment
когда наступит 2, если я воспользуюсь вашим фрагментом? не могли бы вы уточнить это, пожалуйста :) - person Nabia Salman; 02.06.2021
comment
Также как я могу использовать currentValue в любом виджете? - person Nabia Salman; 02.06.2021