count_down_timer.dart 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import 'dart:async';
  2. /// 倒计时
  3. class CountdownTimer {
  4. /// 倒计时时间
  5. final Duration initialDuration;
  6. /// 是否自动开始
  7. final bool autoRestart;
  8. /// 剩余时间
  9. late Duration _remainingTime;
  10. /// 最后更新时间
  11. DateTime? _lastUpdate;
  12. /// 定时器
  13. Timer? _timer;
  14. /// 是否已完成
  15. bool _isCompleted = false;
  16. /// 倒计时更新回调
  17. Function(Duration)? onTick;
  18. /// 倒计时结束回调
  19. Function()? onCompleted;
  20. CountdownTimer({
  21. this.initialDuration = const Duration(minutes: 30),
  22. this.autoRestart = true,
  23. }) {
  24. _remainingTime = initialDuration;
  25. }
  26. Duration get currentDuration => _remainingTime;
  27. /// 开始
  28. void start() {
  29. _lastUpdate = DateTime.now();
  30. _timer?.cancel();
  31. _timer = Timer.periodic(const Duration(milliseconds: 16), _handleTick);
  32. }
  33. /// 暂停
  34. void pause() {
  35. _timer?.cancel();
  36. _lastUpdate = null;
  37. }
  38. /// 重置
  39. void reset() {
  40. _timer?.cancel();
  41. _remainingTime = initialDuration;
  42. _isCompleted = false;
  43. _lastUpdate = null;
  44. onTick?.call(_remainingTime);
  45. }
  46. /// 结束倒计时
  47. void dispose() {
  48. _timer?.cancel();
  49. _timer = null;
  50. }
  51. /// 处理更新
  52. void _handleTick(Timer timer) {
  53. if (_lastUpdate == null) return;
  54. final now = DateTime.now();
  55. final elapsed = now.difference(_lastUpdate!);
  56. if (!_isCompleted) {
  57. _remainingTime -= elapsed;
  58. if (_remainingTime <= Duration.zero) {
  59. _remainingTime = Duration.zero;
  60. _isCompleted = true;
  61. onCompleted?.call();
  62. }
  63. } else if (autoRestart) {
  64. _remainingTime = initialDuration - elapsed;
  65. _isCompleted = false;
  66. }
  67. _lastUpdate = now;
  68. onTick?.call(_remainingTime);
  69. }
  70. /// 格式化时间,格式:分:秒:毫秒
  71. static String format(Duration duration) {
  72. String twoDigits(int n) => n.toString().padLeft(2, '0');
  73. String threeDigits(int n) => n.toString().padLeft(2, '0').substring(0, 2);
  74. int milliseconds = (duration.inMicroseconds ~/ 1000) % 1000;
  75. return "${twoDigits(duration.inMinutes)}:"
  76. "${twoDigits(duration.inSeconds % 60)}:"
  77. "${threeDigits(milliseconds)}";
  78. }
  79. }