count_down_text.dart 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. ///倒计时文本
  4. class CountDownText extends StatefulWidget {
  5. final TextStyle? textStyle;
  6. final CountDownTextController controller;
  7. const CountDownText({super.key, required this.controller, this.textStyle});
  8. @override
  9. State<CountDownText> createState() => _CountDownTextState();
  10. }
  11. class _CountDownTextState extends State<CountDownText> {
  12. @override
  13. void initState() {
  14. super.initState();
  15. widget.controller.countText.addListener(_onUpdateCountText);
  16. }
  17. void _onUpdateCountText() {
  18. setState(() {});
  19. }
  20. @override
  21. void dispose() {
  22. super.dispose();
  23. widget.controller.countText.removeListener(_onUpdateCountText);
  24. widget.controller.stopCount();
  25. }
  26. @override
  27. Widget build(BuildContext context) {
  28. return Text(
  29. widget.controller.countText.value,
  30. style: widget.textStyle,
  31. );
  32. }
  33. }
  34. class CountDownTextController {
  35. ValueNotifier<String>? _countText;
  36. ValueNotifier<String> get countText => _countText ??= ValueNotifier("");
  37. void Function(int tick, bool complete)? onCount;
  38. Timer? _countTimer;
  39. CountDownTextController(this.onCount);
  40. bool get isCounting => _countTimer != null;
  41. void startCount(int time) {
  42. if (isCounting) {
  43. return;
  44. }
  45. if (time <= 0) {
  46. onCount?.call(0, true);
  47. return;
  48. }
  49. _countTimer = Timer.periodic(const Duration(seconds: 1), (tick) {
  50. int left = time - tick.tick;
  51. bool compelte = left <= 0;
  52. if (compelte) {
  53. _timeUp();
  54. } else {
  55. countText.value = "$left";
  56. }
  57. onCount?.call(tick.tick, compelte);
  58. });
  59. countText.value = "$time";
  60. }
  61. void stopCount() {
  62. _countTimer?.cancel();
  63. _countTimer = null;
  64. countText.value = "";
  65. }
  66. void _timeUp() {
  67. stopCount();
  68. }
  69. void dispose() {
  70. _countText?.dispose();
  71. _countText = null;
  72. }
  73. }