Flutter调用StopWatchWidget仅显计时器及背景的问题求助
问题修复:跳转后StopWatchWidget的AppBar和顶部Container不显示
核心问题
你给计时器外层Container硬写了height: 665,从Sune_CLL页面跳转后,屏幕可用高度因导航栈叠加(原页面AppBar + 新页面AppBar)缩水,固定高度的容器直接撑满剩余空间,把顶部的AppBar和Container挤到可视区域外。另外每次点击计时器都会创建新的Timer,旧Timer未取消会重复触发setState,加剧布局异常。
修复方案
1. 替换固定高度为自适应布局
删掉计时器外层的固定高度Container,改用Expanded让它自动填充剩余屏幕空间:
// 原代码 Center( child: Container( height: 665, child: TextButton(...) ), ) // 修改后 Expanded( child: Center( child: TextButton( style: ButtonStyle( overlayColor: MaterialStateProperty.all(Colors.transparent), ), onPressed: startStopWatch, child: Padding( padding: const EdgeInsets.only(bottom: 145.0), child: Text( stopWatchText, style: const TextStyle(fontSize: 50, color: Colors.white), ), ), ), ), )
2. 优化Timer管理,避免重复回调
添加变量保存Timer实例,操作时先取消旧Timer,页面销毁时清理资源:
class StopWatchWidgetState extends State<StopWatchWidget> { final Stopwatch _stopwatch = Stopwatch(); String stopWatchText = '00:00'; Timer? _timer; // 新增变量存储计时器 void startStopWatch() { _timer?.cancel(); // 先取消旧计时器 if (_stopwatch.isRunning) { _stopwatch.stop(); } else { stopWatchText = '00:00'; _stopwatch.reset(); _stopwatch.start(); } // 改为100ms刷新一次,1ms过于浪费性能 _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) { setState(() { if (!_stopwatch.isRunning) { timer.cancel(); _timer = null; } stopWatchText = '${(_stopwatch.elapsed.inMinutes % 60).toString().padLeft(2, '0')}:${(_stopwatch.elapsed.inSeconds % 60).toString().padLeft(2, '0')}'; }); }); } @override void dispose() { _timer?.cancel(); // 页面销毁时清理计时器 super.dispose(); } // ... 其他代码保持不变 }
3. 调整Column布局(可选)
给Column添加mainAxisSize: MainAxisSize.max,确保布局撑满整个屏幕:
body: Column( mainAxisSize: MainAxisSize.max, children: [ Container( height: 60, width: double.infinity, child: ParentWidget(), ), const SizedBox(height: 10), Expanded(...), // 替换后的Expanded组件 ], )
注意事项
- 禁止直接调用
StopWatchWidgetState类,必须通过StopWatchWidget实例跳转页面,直接调用State类违反Flutter框架规范,会导致上下文异常。 - 计时器刷新间隔不要设为1ms,人眼无法分辨这么高的频率,会造成不必要的性能消耗,100ms足够保证显示流畅。
内容的提问来源于stack exchange,提问作者Spicy Pumpkin
相关产品推荐
相关产品推荐

