import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'constants.dart'; class TimersPage extends StatefulWidget { const TimersPage({ super.key, }); @override State createState() => _TimersPageState(); } class _TimersPageState extends State with TickerProviderStateMixin{ late Animation animation; late AnimationController controller; // late double targetProgress; // late double currentProgress; // late double animationDurationSeconds; double targetProgress = 1; double currentProgress = 0; double animationDurationSeconds = 10; int counts = 5; @override void initState() { super.initState(); controller = AnimationController( vsync: this, duration: Duration(seconds: animationDurationSeconds.toInt()), ); animation = Tween( begin: currentProgress, end: targetProgress, ).animate(controller) ..addListener(() { setState(() { currentProgress = animation.value; }); }); } @override Widget build(BuildContext context) { final theme = Theme.of(context); var timerContainerCardColorAlpha = theme.colorScheme.primaryContainer.withAlpha(0); // Used to fill timer container card and make the layout uniform Card timerBlankCard(Color color) { return Card( color: color, elevation: 0.0, borderOnForeground: false, child: ListTile( title: Text('', style: theme.textTheme.titleLarge!.copyWith(color: theme.colorScheme.onPrimaryContainer)), subtitle: const Text('') ), ); } Stream _dateTimeStream() { // 使用Stream.periodic创建一个每秒更新一次的时间流 return Stream.periodic(Duration(seconds: 1), (_) => DateTime.now()); } return Scaffold( body: Container( color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.3), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: Container( margin: const EdgeInsets.all(14.0), // margin: const EdgeInsets.all(12.0), // padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( color: Colors.transparent, borderRadius: myBorderRadius, ), child: Column( children: [ StreamBuilder( stream: _dateTimeStream(), builder: (context, snapshot) { return Text( DateFormat.Hm().format(DateTime.now()), style: theme.textTheme.displayLarge!.copyWith(color: theme.colorScheme.primary), ); }, ), Text( DateFormat('EEEE, MMMM dd').format(DateTime.now()), style: theme.textTheme.titleLarge!.copyWith(color: theme.colorScheme.secondary), ), ], ), ), ), Expanded( child: ListView.builder( itemCount: counts, itemBuilder: (context, index) { return GestureDetector( onTap: () { controller.forward(); }, onLongPress: () { controller.reset(); }, child: Padding( padding: const EdgeInsets.symmetric(horizontal:16.0, vertical:2.0), child: Stack( children: [ Container( // Card background decoration: BoxDecoration( color: theme.colorScheme.secondaryContainer.withAlpha(60), borderRadius: myBorderRadius, ), child: timerBlankCard(timerContainerCardColorAlpha), ), AnimatedContainer( // Progress bar duration: Duration(seconds: animationDurationSeconds.toInt()), alignment: Alignment.centerLeft, width: MediaQuery.of(context).size.width * currentProgress, child: timerBlankCard(theme.colorScheme.primaryContainer.withAlpha(192)), ), Card( // Time and text color: timerContainerCardColorAlpha, elevation: 0.0, borderOnForeground: false, child: ListTile( title: Text( '12:34', style: theme.textTheme.titleLarge!.copyWith(color: theme.colorScheme.primary), ), subtitle: const Text( 'Countdown: 05:00', ), ), ), ], ) ), ); }, ), ), ], ), ), ); } }