Flutter实现Card点击暂停/恢复、双击重置倒计时功能
解决neon_circular_timer控制器为空及Card点击控制倒计时的问题
问题核心错误点
- 控制器定义无效:原代码中
your_controller返回的是00,并非有效的CountDownController实例,导致调用方法时返回null - 状态管理缺失:
Pads是无状态组件,无法维护计时器的状态变化,需要改为有状态组件 - 点击事件未完整实现:第二个Card未添加点击监听,且未实现暂停/恢复的切换逻辑与双击重置功能
- 控制器复用冲突:两个计时器共用无效的控制器,无法独立控制
解决方案步骤
- 将
Pads改为StatefulWidget,用于维护两个独立的CountDownController实例 - 为每个Card添加
InkWell包裹,实现单击切换暂停/恢复、双击重置的逻辑 - 通过
controller.isPaused判断当前计时器状态,实现暂停与恢复的切换 - 为每个
NeonCircularTimer绑定对应的独立控制器
修复后的完整代码
import 'package:flutter/material.dart'; import 'package:neon_circular_timer/neon_circular_timer.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.teal, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: const Pads(), ); } } class Pads extends StatefulWidget { const Pads({super.key}); @override State<Pads> createState() => _PadsState(); } class _PadsState extends State<Pads> { // 为两个计时器创建独立的控制器 final CountDownController _blueTimerController = CountDownController(); final CountDownController _greenTimerController = CountDownController(); // 切换暂停/恢复的通用方法 void _togglePauseResume(CountDownController controller) { if (controller.isPaused) { controller.resume(); } else { controller.pause(); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('CHESS APP'), leading: const Icon(Icons.image_aspect_ratio), toolbarHeight: 50, ), body: Column(children: <Widget>[ SizedBox( height: 360, width: 500, child: InkWell( onTap: () => _togglePauseResume(_blueTimerController), onDoubleTap: () => _blueTimerController.reset(), child: Card( elevation: 20, shadowColor: Colors.blueGrey, color: Colors.blueAccent, margin: const EdgeInsets.all(10), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(10))), clipBehavior: Clip.hardEdge, child: NeonCircularTimer( width: 200, duration: 300, isReverse: true, isReverseAnimation: true, controller: _blueTimerController, isTimerTextShown: true, neumorphicEffect: true, innerFillColor: Colors.black12, backgroudColor: Colors.blueAccent, innerFillGradient: LinearGradient(colors: [ Colors.greenAccent.shade200, Colors.blueAccent.shade400 ]), neonGradient: LinearGradient(colors: [ Colors.greenAccent.shade200, Colors.blueAccent.shade400 ]), ), ), ), ), SizedBox( height: 360, width: 500, child: InkWell( onTap: () => _togglePauseResume(_greenTimerController), onDoubleTap: () => _greenTimerController.reset(), child: Card( elevation: 20, shadowColor: Colors.blueGrey, color: Colors.green, margin: const EdgeInsets.all(10), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(10))), clipBehavior: Clip.hardEdge, child: NeonCircularTimer( width: 200, duration: 300, isReverse: true, isReverseAnimation: true, controller: _greenTimerController, isTimerTextShown: true, neumorphicEffect: true, innerFillColor: Colors.black12, backgroudColor: Colors.green, innerFillGradient: LinearGradient(colors: [ Colors.greenAccent.shade200, Colors.blueAccent.shade400 ]), neonGradient: LinearGradient(colors: [ Colors.greenAccent.shade200, Colors.blueAccent.shade400 ]), ), ), ), ) ]), ); } }
关键修改说明
- 状态组件转换:
Pads改为StatefulWidget,可以在状态类中创建并维护控制器实例 - 独立控制器:为两个计时器分别创建
_blueTimerController和_greenTimerController,避免操作互相影响 - 点击逻辑实现:
- 单击通过
_togglePauseResume方法,根据controller.isPaused状态切换暂停/恢复 - 双击直接调用
controller.reset()实现重置
- 单击通过
- InkWell包裹:每个Card都用
InkWell包裹,解决Card只能有一个child的问题,同时添加点击事件监听
内容的提问来源于stack exchange,提问作者Atharv More
相关产品推荐
相关产品推荐

