Пусть StreamBuilder обрабатывает потоки, которые не создаются при первом вызове BLoC - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь добавить таймер обратного отсчета из библиотеки дротиков 'quiver' в виджет StreamBuilder.Я использую шаблон BLoC для управления состоянием.

Таймер обратного отсчета на экране просмотра активируется нажатием кнопки на экране просмотра.Это создает новый CountdownTimer в моем блоке.Слой вида имеет виджет StreamBuilder, который прослушивает поток CountdownTimer.Однако после первого запуска, когда экземпляр CountdownTimer создается во второй раз, время не отображается на экране просмотра.Я пробовал несколько вариантов:

  1. Используйте метод listen для экземпляра CountdownTimer, чтобы добавить события в текущий поток, который StreamBuilder слушает.

  2. Сделать виджет, содержащий StreamBuilder, виджетом с сохранением состояния и вызывать setState при каждом запуске нового таймера, чтобы StreamBuilder создавал новую подписку.

  3. Передача экземпляра CountdownTimer из экземпляраблок во второй поток, на который подписывается StreamBuilder;тем не менее, канал вызывает close () после завершения, и последующие таймеры не отображаются.

В общем, что было бы лучше, если бы StreamBuilder имел дело с несколькими потоками, которые не были созданыкогда сначала вызывается блок (т. е. поток становится активным после загрузки представления и ввода данных пользователем).Объединение нового потока с открытым потоком выглядит как вариант, но затем создается новый поток, и я не смог найти способ прослушать этот новый поток с помощью StreamBuilder.

Пример:

BLoC:

class TimerBloc {

  CountdownTimer countdownTimer =
    CountdownTimer(Duration(seconds: 0), Duration(seconds: 1));

  PublishSubject<CountdownTimer> timerStream = PublishSubject<CountdownTimer>();

  Duration get userSetTime {
    if (sliderTime.value == null) {
      return Duration(seconds: 25);
    }

    return Duration(seconds: int.parse(sliderTime.value.round().toString()));
  }

  start() {
    if (countdownTimer.isRunning) {
      countdownTimer.cancel();
    }

    countdownTimer = CountdownTimer(userSetTime, Duration(seconds: 1));

    countdownTimer.listen((tickEvent) {
      timerStream.sink.add(tickEvent);
    });
  }

Виджет отображения:

Widget _buildDisplay(bloc) {
    return StreamBuilder(
      stream: bloc.timerStream.stream,
      builder: (context, AsyncSnapshot<CountdownTimer> snapshot) {
        if (snapshot.hasData) {
          int info = snapshot.data.remaining.inSeconds; [...]
...