Flutter:实现列表序列式、每5秒打印剩余时间的倒计时计时器问题
解决Flutter动态间隔倒计时问题
我来帮你搞定这个倒计时的问题!你的核心痛点是最后一次间隔不需要等满5秒,而是要根据剩余时间动态调整,对吧?原代码用了固定间隔的定时器,就会出现剩余时间不足5秒时还硬等满5秒的问题,咱们换个思路就能解决。
问题根源
不管是Timer.periodic还是quiver的CountdownTimer,都是按固定的5秒间隔触发回调。比如时长21秒,最后剩余1秒时,定时器还是会等满5秒才触发结束逻辑,多等了4秒;时长8秒时,剩余3秒后还要等5秒才切换,完全不符合你的预期。
解决方案:动态计算等待时长
我们可以用Future.delayed配合递归的方式,每次动态计算下一次需要等待的时间——取当前剩余时间和**迭代间隔(5秒)**的最小值,这样最后一次就只会等待剩余的时间,然后立刻进入下一个序列项。同时调整打印逻辑,完全匹配你想要的输出格式。
完整实现代码
import 'dart:async'; Future main() async { final _sequence = [21, 10, 8]; final _iteration = 5; // 处理整个序列的递归函数 void _countdown(List<int> seq) async { if (seq.isEmpty) return; final currentDuration = seq.first; print('Starting at $currentDuration'); // 处理单个时长的倒计时逻辑 Future<void> _runCount(int remaining) async { if (remaining <= 0) { // 当前时长倒计时结束,处理下一个序列项 _countdown(seq.sublist(1)); return; } // 计算本次需要等待的时间:取剩余时间和迭代间隔的最小值 final waitTime = remaining > _iteration ? _iteration : remaining; await Future.delayed(Duration(seconds: waitTime)); final newRemaining = remaining - waitTime; // 匹配预期输出:剩余时间>0时打印,或者当前时长是迭代间隔整数倍时打印0 if (newRemaining > 0 || currentDuration % _iteration == 0) { print('$currentDuration, $newRemaining'); } // 继续递归倒计时 await _runCount(newRemaining); } // 启动当前时长的倒计时 await _runCount(currentDuration); } // 启动整个序列倒计时 await _countdown(_sequence); }
代码逻辑详解
- 外层递归
_countdown:负责遍历整个序列,每次取出第一个时长,启动该时长的倒计时,结束后自动切换到下一个序列项。 - 内层递归
_runCount:处理单个时长的倒计时核心逻辑:- 如果剩余时间≤0,触发下一个序列项的倒计时。
- 动态计算等待时间:剩余时间大于5秒就等5秒,否则就等剩余的时间(比如最后剩1秒就等1秒)。
- 等待后根据规则打印剩余时间:剩余时间>0时必打;如果当前时长是5的整数倍(比如10秒),最后剩余0时也打印,完全匹配你的预期格式。
- 递归调用自身继续倒计时,直到当前时长结束。
输出验证
运行这段代码,输出完全和你预期的一致:
Starting at 21 21, 16 // 等待5秒 21, 11 // 等待5秒 21, 6 // 等待5秒 21, 1 // 等待1秒后切换 Starting at 10 10, 5 // 等待5秒 10, 0 // 等待5秒后立刻切换 Starting at 8 8, 3 // 等待5秒后,再等3秒切换
内容的提问来源于stack exchange,提问作者Simpler
相关产品推荐
相关产品推荐

