| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import 'dart:async';
- /// 倒计时
- class CountdownTimer {
- /// 倒计时时间
- final Duration initialDuration;
- /// 是否自动开始
- final bool autoRestart;
- /// 剩余时间
- late Duration _remainingTime;
- /// 最后更新时间
- DateTime? _lastUpdate;
- /// 定时器
- Timer? _timer;
- /// 是否已完成
- bool _isCompleted = false;
- /// 倒计时更新回调
- Function(Duration)? onTick;
- /// 倒计时结束回调
- Function()? onCompleted;
- CountdownTimer({
- this.initialDuration = const Duration(minutes: 30),
- this.autoRestart = true,
- }) {
- _remainingTime = initialDuration;
- }
- Duration get currentDuration => _remainingTime;
- /// 开始
- void start() {
- _lastUpdate = DateTime.now();
- _timer?.cancel();
- _timer = Timer.periodic(const Duration(milliseconds: 16), _handleTick);
- }
- /// 暂停
- void pause() {
- _timer?.cancel();
- _lastUpdate = null;
- }
- /// 重置
- void reset() {
- _timer?.cancel();
- _remainingTime = initialDuration;
- _isCompleted = false;
- _lastUpdate = null;
- onTick?.call(_remainingTime);
- }
- /// 结束倒计时
- void dispose() {
- _timer?.cancel();
- _timer = null;
- }
- /// 处理更新
- void _handleTick(Timer timer) {
- if (_lastUpdate == null) return;
- final now = DateTime.now();
- final elapsed = now.difference(_lastUpdate!);
- if (!_isCompleted) {
- _remainingTime -= elapsed;
- if (_remainingTime <= Duration.zero) {
- _remainingTime = Duration.zero;
- _isCompleted = true;
- onCompleted?.call();
- }
- } else if (autoRestart) {
- _remainingTime = initialDuration - elapsed;
- _isCompleted = false;
- }
- _lastUpdate = now;
- onTick?.call(_remainingTime);
- }
- /// 格式化时间,格式:分:秒:毫秒
- static String format(Duration duration) {
- String twoDigits(int n) => n.toString().padLeft(2, '0');
- String threeDigits(int n) => n.toString().padLeft(2, '0').substring(0, 2);
- int milliseconds = (duration.inMicroseconds ~/ 1000) % 1000;
- return "${twoDigits(duration.inMinutes)}:"
- "${twoDigits(duration.inSeconds % 60)}:"
- "${threeDigits(milliseconds)}";
- }
- }
|