counting_button.dart 2.0 KB

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