題記
—— 執劍天涯,從你的點滴積累開始,所及之處,必精益求精,即是折騰每一天。
本文是異步程式設計的定時器政策篇章,通過Timer來實作。
定時器的使用場景一般如下
- 間隔一定的時間循環發起查詢
- 倒計時
通過Timer實作間隔一定時間的循環執行
Timer的periodic函數開啟一個循環執行的任務,其參數一用來配制間隔執行這個任務的時間,參數二用來配置具體執行的任務,在使用時需要注意有建立就要有銷毀,以避免記憶體洩漏,如開啟一個間隔1秒的定時任務,如下代碼清單1-1所示:
class _FutureLoopTestPageState extends State {
///聲明變量
Timer _timer;
@override
void initState() {
super.initState();
///循環執行
///間隔1秒
_timer = Timer.periodic(Duration(milliseconds: 1000), (timer) {
///定時任務
});
}
@override
void dispose() {
///取消計時器
_timer.cancel();
super.dispose();
}
...
}
實作一個APP啟動頁面的倒計時
如下圖所示為常見App的一個啟動頁面的倒計時顯示效果,對應代碼清單 1-3.

對應的實作代碼如下:
///代碼清單 1-3 實作一個倒計時
class FutureLoopTestPage2 extends StatefulWidget {
@override
_FutureLoopTestPageState createState() => _FutureLoopTestPageState();
}
//lib/code/main_data.dart
class _FutureLoopTestPageState extends State<FutureLoopTestPage2> {
///聲明變量
Timer _timer;
///記錄目前的時間
int curentTimer = 0;
@override
void initState() {
super.initState();
///循環執行
///間隔1秒
_timer = Timer.periodic(Duration(milliseconds: 1000), (timer) {
///自增
curentTimer++;
///到5秒後停止
if (curentTimer == 5) {
_timer.cancel();
}
setState(() {});
});
}
@override
void dispose() {
///取消計時器
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("倒計時"),
),
backgroundColor: Colors.white,
///填充布局
body: Container(
padding: EdgeInsets.all(20),
width: double.infinity,
height: double.infinity,
child: Column(
children: [
///層疊布局将進度與文字疊在一起
Stack(
///子Widget居中
alignment: Alignment.center,
children: [
///圓形進度
CircularProgressIndicator(
///目前訓示的進度 0.0 -1.0
value: curentTimer / 5,
),
///顯示的文本
Text("${5-curentTimer}"),
],
)
],
)),
);
}
}
在上述代碼清單 1-3 中所示的效果,圓形進度執行的有點死闆的效果,如下圖所示為優化後的效果,給人的視覺效果比較舒适,對應代碼清單1-4。
///代碼清單 1-4
class FutureLoopTestPage3 extends StatefulWidget {
@override
_FutureLoopTestPageState createState() => _FutureLoopTestPageState();
}
//lib/code/main_data.dart
class _FutureLoopTestPageState extends State<FutureLoopTestPage3> {
///聲明變量
Timer _timer;
///記錄目前的時間
int curentTimer = 0;
@override
void initState() {
super.initState();
///循環執行
///間隔1秒
_timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
///自增
curentTimer+=100;
///到5秒後停止
if (curentTimer >= 5000) {
_timer.cancel();
}
setState(() {});
});
}
@override
void dispose() {
///取消計時器
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("倒計時"),
),
backgroundColor: Colors.white,
///填充布局
body: Container(
padding: EdgeInsets.all(20),
width: double.infinity,
height: double.infinity,
child: Column(
children: [
///層疊布局将進度與文字疊在一起
Stack(
///子Widget居中
alignment: Alignment.center,
children: [
///圓形進度
CircularProgressIndicator(
///目前訓示的進度 0.0 -1.0
value: curentTimer / 5000,
),
///顯示的文本
Text("${(curentTimer/1000).toInt()}"),
],
)
],
)),
);
}
}
代碼清單 1-3 與代碼 清單1-4中所示的效果有完全不同的視覺效果,在代碼實作的方式上隻是重新整理頻率的不一樣。
完畢