Flutter使用circular_countdown_timer返回页面时计时器重启如何保存状态
解决方案:circular_countdown_timer计时状态持久化
你的问题核心原因是每次进入页面都会重新初始化CountDownController(),且initialDuration固定写为0,页面销毁时控制器和当前计时进度也会被同步回收,重新进入自然会从零开始计时。可以通过以下方式保留计时状态:
实现逻辑
- 将计时状态抽离到页面对象之外存储,可以用状态管理框架(Provider/GetX/Bloc等)持有,也可以用
SharedPreferences做持久化存储,实现杀进程重启也能恢复进度 - 页面销毁前记录当前剩余计时时长,再次进入页面时把保存的时长赋值给
initialDuration参数 - 不要每次进入页面都新建
CountDownController,将控制器放到全局或者状态管理类中持有
代码示例
// 页面内定义变量,也可以放到你的状态管理类中全局持有 late CountDownController _countDownController; int _remainingDuration = 0; @override void initState() { super.initState(); // 初始化时读取之前保存的剩余时长,首次进入默认是0即可 _remainingDuration = getSavedDuration(); // 该方法自行实现,比如从SharedPreferences、状态容器中读取 _countDownController = CountDownController(); } @override void dispose() { // 页面销毁前保存当前剩余时长 _remainingDuration = int.parse(_countDownController.getTime() ?? "0"); saveDuration(_remainingDuration); // 该方法自行实现,把剩余时长写入持久层/状态容器 super.dispose(); } // 修改后的倒计时组件配置 CircularCountDownTimer( duration: 10, initialDuration: _remainingDuration, // 替换为读取到的历史剩余时长,不要写死0 controller: _countDownController, // 复用持有的控制器,不要每次新建 width: 55.0, height: 85.0, ringColor: Color(0x30A6CA).withOpacity(0.1), ringGradient: null, fillColor: Color(0xFF30A6CA), fillGradient: null, backgroundColor: Colors.transparent, backgroundGradient: null, strokeWidth: 10.0, strokeCap: StrokeCap.round, textStyle: GoogleFonts.roboto( fontSize: 14.0, color: Colors.black, fontWeight: FontWeight.bold, ), textFormat: CountdownTextFormat.MM_SS, isReverse: true, isReverseAnimation: false, isTimerTextShown: true, autoStart: true, onStart: () {}, onComplete: () { // 计时结束后清空存储的剩余时长,避免下次进入重复计时 saveDuration(0); }, ),
注意事项
- 如果需要实现后台挂起/杀进程重启后进度依然准确,可以把计时开始的时间戳和总时长一起持久化存储,下次进入页面时计算当前时间和历史开始时间的差值,就能得到精准的剩余时长
- 如果你的页面只是被压入路由栈没有销毁,只要不重复初始化控制器和初始时长,返回页面时会自动恢复之前的进度,不需要额外做持久化存储
内容的提问来源于stack exchange,提问作者Wassef Hassine
相关产品推荐
相关产品推荐

