You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Flutter Bloc实现每秒更新的天数统计功能

实现Bloc每秒更新流逝时长的方案

1. 新增承载实时时长的状态类

首先需要添加一个专门的状态,用来传递每秒计算出的流逝时长数据:

class OnTimerUpdateState extends DayCountingState {
  final int totalSeconds;
  final int days;
  final int hours;
  final int minutes;
  final int seconds;

  OnTimerUpdateState({
    required this.totalSeconds,
    required this.days,
    required this.hours,
    required this.minutes,
    required this.seconds,
  });
}

2. 修改Bloc逻辑,加入定时器实现每秒更新

在Bloc中添加定时器变量存储初始日期,获取到初始日期后启动定时器,每秒计算时间差并发送状态更新:

class DayCountingBloc extends Bloc<DayCountingEvent, DayCountingState> {
  final RetrieveBeginDate _retrieveBeginDate;
  final StoreBeginDate _storeBeginDate;
  Timer? _updateTimer;
  DateTime? _initialDate; // 缓存获取到的初始日期

  DayCountingBloc(
      RetrieveBeginDate retrieveBeginDate, StoreBeginDate storeBeginDate)
      : _retrieveBeginDate = retrieveBeginDate,
        _storeBeginDate = storeBeginDate,
        super(DayCountingInitial()) {
    on<DayCountingEvent>((event, emit) {
      emit(OnLoadingState());
    });

    on<RetrieveDateEvent>((event, emit) async {
      final res = await _retrieveBeginDate(NoParams());
      _initialDate = res;
      emit(OnRetrieveSuccessState(date: res));
      // 获取日期后启动每秒更新的定时器
      _startUpdateTimer(emit);
    });

    on<StoreDateEvent>((event, emit) async {
      final res = await _storeBeginDate(event.date);
      if (res) {
        _initialDate = event.date;
        emit(OnStoreSuccessState());
        // 存储日期成功后启动定时器
        _startUpdateTimer(emit);
      } else {
        emit(OnFailureState());
      }
    });
  }

  // 启动定时器,每秒计算时间差并发送状态
  void _startUpdateTimer(Emitter<DayCountingState> emit) {
    // 先取消旧定时器,避免重复触发
    _updateTimer?.cancel();
    _updateTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (_initialDate == null) return;
      final now = DateTime.now();
      final difference = now.difference(_initialDate!);
      // 拆分时间差为天、时、分、秒
      final totalSeconds = difference.inSeconds;
      final days = difference.inDays;
      final hours = difference.inHours % 24;
      final minutes = difference.inMinutes % 60;
      final seconds = difference.inSeconds % 60;
      // 发送更新状态
      emit(OnTimerUpdateState(
        totalSeconds: totalSeconds,
        days: days,
        hours: hours,
        minutes: minutes,
        seconds: seconds,
      ));
    });
  }

  // 关闭Bloc时销毁定时器,防止内存泄漏
  @override
  Future<void> close() {
    _updateTimer?.cancel();
    return super.close();
  }
}

3. UI层监听状态实时展示

在UI组件中监听OnTimerUpdateState,实时渲染计算出的流逝时长:

BlocBuilder<DayCountingBloc, DayCountingState>(
  builder: (context, state) {
    if (state is OnTimerUpdateState) {
      return Text(
        '已流逝: ${state.days}天 ${state.hours}时 ${state.minutes}分 ${state.seconds}秒',
        style: const TextStyle(fontSize: 18),
      );
    }
    // 其他状态的UI处理逻辑
    return const Text('加载中...');
  },
)

关键注意点

  • 每次启动定时器前先取消旧实例,避免多个定时器同时运行
  • 必须在Bloc的close方法中销毁定时器,防止内存泄漏
  • 如果初始日期未获取到(比如首次打开还未存储),定时器不会执行计算,需先完成初始日期的存储逻辑

内容的提问来源于stack exchange,提问作者HaBuiDuc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:33:21