import 'dart:async'; import 'package:flutter/material.dart'; ///倒计时文本 class CountDownText extends StatefulWidget { final TextStyle? textStyle; final CountDownTextController controller; const CountDownText({super.key, required this.controller, this.textStyle}); @override State createState() => _CountDownTextState(); } class _CountDownTextState extends State { @override void initState() { super.initState(); widget.controller.countText.addListener(_onUpdateCountText); } void _onUpdateCountText() { setState(() {}); } @override void dispose() { super.dispose(); widget.controller.countText.removeListener(_onUpdateCountText); widget.controller.stopCount(); } @override Widget build(BuildContext context) { return Text( widget.controller.countText.value, style: widget.textStyle, ); } } class CountDownTextController { ValueNotifier? _countText; ValueNotifier get countText => _countText ??= ValueNotifier(""); void Function(int tick, bool complete)? onCount; Timer? _countTimer; CountDownTextController(this.onCount); bool get isCounting => _countTimer != null; void startCount(int time) { if (isCounting) { return; } if (time <= 0) { onCount?.call(0, true); return; } _countTimer = Timer.periodic(const Duration(seconds: 1), (tick) { int left = time - tick.tick; bool compelte = left <= 0; if (compelte) { _timeUp(); } else { countText.value = "$left"; } onCount?.call(tick.tick, compelte); }); countText.value = "$time"; } void stopCount() { _countTimer?.cancel(); _countTimer = null; countText.value = ""; } void _timeUp() { stopCount(); } void dispose() { _countText?.dispose(); _countText = null; } }