timer_bloc.dart 2.28 KB
import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wow_english/common/widgets/timer_ticker.dart';

part 'timer_event.dart';
part 'timer_state.dart';

class TimerBloc extends Bloc<TimerEvent, TimerState> {
  /// 定时器时间
  static const int _duration = 60;
  /// 定时器数据流
  final TimerTicker _ticker;
  /// 是否正在计时
  bool _isCountTimer = false;

  bool get isCountTimer => _isCountTimer;
  // 流订阅
  StreamSubscription<int>? _tickerSubscription;
  TimerBloc({required TimerTicker ticker})
      :_ticker = ticker,
        super(const TimerInitial(_duration)) {
    on<StartEvent>(_onStarted);
    on<TickEvent>(_onTicked);
    on<PausedEvent>(_onPaused);
    on<ResumedEvent>(_onResumed);
    on<ResetEvent>(_onReset);
  }

  @override
  Future<void> close() {
    _tickerSubscription?.cancel();
    return super.close();
  }

  /// 开始计时
  void _onStarted(StartEvent event,Emitter<TimerState> emitter) async {
    _isCountTimer = true;
    emitter(RunningState(event.duration));
    _tickerSubscription?.cancel();
    _tickerSubscription = _ticker
        .tick(ticks: event.duration)
        .listen((event) => add(TickEvent(duration: event)));
  }

  /// 计时中,判断是否剩余时间
  void _onTicked(TickEvent event,Emitter<TimerState> emitter) async {
    if(event.duration > 0) {
      emitter(RunningState(event.duration));
    } else {
      _isCountTimer = false;
      emitter(const FinishedState());
    }
  }

  ///暂停,判断当时是否state为PausedState类型,之后暂停订阅,发送暂停state
  void _onPaused(PausedEvent event, Emitter<TimerState> emit) async{
    if( state is RunningState) {
      _tickerSubscription?.pause();
      emit(PausedState(state.duration));
    }
  }

  /// 恢复,我们判断当前state为暂停状态后,进行恢复
  void _onResumed(ResumedEvent event, Emitter<TimerState> emit) async{
    if( state is PausedState) {
      _tickerSubscription?.resume();
      emit(RunningState(state.duration));
    }
  }

  /// 重置,初始化
  void _onReset(ResetEvent event ,Emitter<TimerState> emit) async{
    _tickerSubscription?.cancel();
    _isCountTimer = false;
    emit(const TimerInitial(_duration));
  }
}