import 'dart:async'; import 'package:flutter/material.dart'; class ActivityCountdownView extends StatefulWidget { final Duration duration; final TextStyle? textStyle; final BoxDecoration? timeBgBoxDecoration; final double? timeItemWidth; final double? timeItemHeight; final BoxFit bgFit; final EdgeInsetsGeometry contentPadding; final Widget? separator; final VoidCallback? onFinish; const ActivityCountdownView({ super.key, required this.duration, this.timeBgBoxDecoration, this.textStyle, this.timeItemWidth, this.timeItemHeight, this.bgFit = BoxFit.contain, this.contentPadding = const EdgeInsets.all(4), this.separator, this.onFinish, }); @override State createState() => _ActivityCountdownViewState(); } class _ActivityCountdownViewState extends State { late Duration _remaining; Timer? _timer; @override void initState() { super.initState(); _remaining = widget.duration; _startTimer(); } void _startTimer() { _timer = Timer.periodic(const Duration(seconds: 1), (_) { if (_remaining.inSeconds <= 1) { _timer?.cancel(); widget.onFinish?.call(); setState(() { _remaining = const Duration(seconds: 0); }); } else { setState(() { _remaining -= const Duration(seconds: 1); }); } }); } String _twoDigits(int n) => n.toString().padLeft(2, '0'); @override Widget build(BuildContext context) { final hours = _twoDigits(_remaining.inHours); final minutes = _twoDigits(_remaining.inMinutes.remainder(60)); final seconds = _twoDigits(_remaining.inSeconds.remainder(60)); return Row( mainAxisSize: MainAxisSize.min, children: [ _buildTimeBox(hours), _buildSeparator(), _buildTimeBox(minutes), _buildSeparator(), _buildTimeBox(seconds), ], ); } /// 自定义时间数字块,2位合并显示 Widget _buildTimeBox(String text) { return Container( width: widget.timeItemWidth, height: widget.timeItemHeight, alignment: Alignment.center, padding: widget.contentPadding, decoration: widget.timeBgBoxDecoration, child: Text( text, maxLines: 1, style: widget.textStyle ?? const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white), ), ); } /// 自定义分隔符(冒号),如果未设置就给默认间距 Widget _buildSeparator() { return widget.separator ?? const SizedBox( width: 4, ); } @override void dispose() { _timer?.cancel(); super.dispose(); } }