counting_button.dart 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. ///计时按钮
  4. class CountingButton extends StatefulWidget {
  5. final CountingButtonController controller;
  6. final VoidCallback? onPressed;
  7. final Widget Function(int count, bool isCounting) onGetChild;
  8. final ButtonStyle? buttonStyle;
  9. const CountingButton(
  10. {super.key,
  11. required this.controller,
  12. required this.onGetChild,
  13. this.onPressed,
  14. this.buttonStyle});
  15. @override
  16. State<CountingButton> createState() => _CountingButtonState();
  17. }
  18. class _CountingButtonState extends State<CountingButton> {
  19. @override
  20. void initState() {
  21. super.initState();
  22. widget.controller.counter.addListener(() {
  23. setState(() {});
  24. });
  25. }
  26. @override
  27. void dispose() {
  28. super.dispose();
  29. widget.controller.dispose();
  30. }
  31. @override
  32. Widget build(BuildContext context) {
  33. return ElevatedButton(
  34. onPressed: _onPressed,
  35. style: widget.buttonStyle ??
  36. ButtonStyle(
  37. backgroundColor:
  38. WidgetStatePropertyAll(Theme.of(context).primaryColor),
  39. elevation: const WidgetStatePropertyAll(0.0)),
  40. child: widget.onGetChild(
  41. widget.controller.counter.value, widget.controller.isCounting));
  42. }
  43. void _onPressed() {
  44. if (widget.controller.counter.value > 0) {
  45. return;
  46. }
  47. widget.onPressed?.call();
  48. }
  49. }
  50. class CountingButtonController {
  51. Timer? _timer;
  52. ValueNotifier<int>? _counter;
  53. ValueNotifier<int> get counter => _counter ??= ValueNotifier(-1);
  54. bool get isCounting => _timer != null;
  55. void start(int count) {
  56. _timer?.cancel();
  57. _timer = Timer.periodic(Duration(seconds: 1), (t) {
  58. counter.value = t.tick;
  59. if (t.tick >= count) {
  60. stop();
  61. }
  62. });
  63. counter.value = 0;
  64. }
  65. void stop() {
  66. _timer?.cancel();
  67. _timer = null;
  68. counter.value = -1;
  69. }
  70. void dispose() {
  71. _counter?.dispose();
  72. _counter = null;
  73. }
  74. }