Inspire - Capo Productions
定时器
延时器
类似 JS 的 setTimeout,在指定时间后执行一次回调。
Future.delayed
dart
// 页面加载后延迟执行
@override
void initState() {
super.initState();
Future.delayed(Duration(milliseconds: 300), () {
print('300ms 后执行');
});
}支持 async/await:
dart
await Future.delayed(Duration(milliseconds: 300));
print('300ms 后执行');周期器
类似 JS 的 setInterval,每隔指定时间执行一次回调。
示例一:轮询获取数据
dart
import 'dart:async';
late Timer timer;
@override
void initState() {
super.initState();
// initState 只执行一次,所以不需要取消 Timer
timer = Timer.periodic(Duration(seconds: 5), (_) {
fetchData();
});
}
@override
void dispose() {
// 取消定时器
timer.cancel();
super.dispose();
}示例二:倒计时按钮
dart
import 'dart:async';
import 'package:flutter/material.dart';
class CountdownButton extends StatefulWidget {
@override
State<CountdownButton> createState() => _CountdownButtonState();
}
class _CountdownButtonState extends State<CountdownButton> {
Timer? _timer;
int _countdown = 10;
void _startTimer() {
_timer?.cancel(); // 可能多次执行 _startTimer 方法,所以需要避免重复启动
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
if (_countdown == 0) {
timer.cancel();
} else {
setState(() {
_countdown--;
});
}
});
}
@override
void dispose() {
_timer?.cancel(); // 页面销毁时一定要关闭Timer!
super.dispose();
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: _startTimer,
child: Text(_countdown == 0 ? '重新发送' : '$_countdown 秒'),
);
}
}常见注意事项
| ⚠️ 问题 | 💡 解决方案 |
|---|---|
| Widget 销毁后 Timer 仍在运行 | 必须在 dispose() 中调用 _timer?.cancel() |
| 多次启动重复计时 | 启动前先 _timer?.cancel() |
| UI 不更新 | 在回调中使用 setState() 更新界面 |
| 后台仍在运行 | 如果页面不需要继续计时,应在离开页面时取消 Timer |
延迟执行 + 循环执行
dart
Future.delayed(Duration(seconds: 1), () {
Timer.periodic(Duration(seconds: 2), (timer) {
print('执行一次');
});
});