Я пытаюсь добавить таймер обратного отсчета из библиотеки дротиков 'quiver' в виджет StreamBuilder
.Я использую шаблон BLoC для управления состоянием.
Таймер обратного отсчета на экране просмотра активируется нажатием кнопки на экране просмотра.Это создает новый CountdownTimer
в моем блоке.Слой вида имеет виджет StreamBuilder
, который прослушивает поток CountdownTimer
.Однако после первого запуска, когда экземпляр CountdownTimer
создается во второй раз, время не отображается на экране просмотра.Я пробовал несколько вариантов:
Используйте метод listen для экземпляра CountdownTimer, чтобы добавить события в текущий поток, который StreamBuilder слушает.
Сделать виджет, содержащий StreamBuilder, виджетом с сохранением состояния и вызывать setState при каждом запуске нового таймера, чтобы StreamBuilder создавал новую подписку.
Передача экземпляра 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; [...]