Flutter如何手势点击修改计时器值 解决isRunning未定义及时间格式化问题
Flutter计时器问题修复方案
1 修复isRunning未定义+点击递增时长问题
错误原因
你之前的isRunning是buildButtons方法内的局部变量,作用域仅在该方法内部,buildTimer方法里的手势回调自然无法访问。
修复步骤
- 首先在State类中新增
isRunning的全局getter,替换局部变量,同时修改固定时长为可修改参数:
// 放在State类的属性定义区域 bool get isRunning => timer?.isActive ?? false; // 初始为5分钟(300秒),设置25分钟的上限 int maxSeconds = 5 * 60; static const int maxLimitSeconds = 25 * 60;
- 然后修改
GestureDetector的onTap回调,加入时长递增逻辑:
onTap: () { if (isRunning) { return; } // 每次点击加5分钟,不超过25分钟上限 if (maxSeconds < maxLimitSeconds) { setState(() { maxSeconds += 5 * 60; // 计时器未运行时同步更新当前秒数,保证显示正确 seconds = maxSeconds; }); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已调整为${maxSeconds~/60}分钟'))); } else { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('时长上限为25分钟'))); } }
- 最后把
buildButtons方法里原来定义局部isRunning的代码删掉,直接用全局getter即可。
2 修复时间显示为分:秒格式
修改buildTime方法的文本显示逻辑,把总秒数换算为分钟和剩余秒数,补零格式化即可:
Widget buildTime() { if (seconds == 0) { return Icon(Icons.done, color: Colors.greenAccent, size: 112); } // 换算分和秒 int minutes = seconds ~/ 60; int remainingSeconds = seconds % 60; // 补零格式化,比如秒数为0时显示为00 String timeStr = '$minutes:${remainingSeconds.toString().padLeft(2, '0')}'; return Text( timeStr, style: TextStyle( fontWeight: FontWeight.bold, color: Colors.white, fontSize: 80, ), ); }
如果你用补充代码里的NumberFormat,也可以直接用:
var f = NumberFormat("00"); String timeStr = '$minutes:${f.format(remainingSeconds)}';
额外注意点
你原来stopTimer方法里的判断if (reset == mounted)逻辑有问题,应该改为判断reset是否为true:
void stopTimer({bool reset = true}) { if (reset) { resetTimer(); } setState(() => timer?.cancel()); }
内容的提问来源于stack exchange,提问作者Bn Minki
相关产品推荐
相关产品推荐

