本文微信公眾號「AndroidTraveler」首發。
今天給大家講講 Flutter 裡面定時器/倒計時的實現。
一般有兩種場景:
- 我只需要你在指定時間結束後回調告訴我。回調只需要一次。
- 我需要你在指定時間結束後回調告訴我。回調可能多次。
下面針對這兩種場景,我們來說下如何在 Flutter 裡面使用。
回調一次的定時器
const timeout = const Duration(seconds: 5);
print('currentTime='+DateTime.now().toString());
Timer(timeout, () {
//到時回調
print('afterTimer='+DateTime.now().toString());
});
這裡我們設置了超時時間為 5 秒。然後啟動一個定時器,等到 5 秒時候到了,就會執行回調方法。
我們在定時器啟動之前和之後都加上了打印日誌,控制檯打印輸出如下:
flutter: currentTime=2019-06-08 13:56:35.347493
flutter: afterTimer=2019-06-08 13:56:40.350412
用法總結起來就是:
1.設置超時時間 timeout
2.啟動定時器 Timer(timeout, callback)
3.處理回調 callback
回調多次的定時器
回調多次的定時器用法和回調一次的差不多,區別有下面兩點:
- API 調用不同
- 需要手動取消,否則會一直回調,因為是週期性的
一樣的我們通過一個簡單的小例子來說明:
int count = 0;
const period = const Duration(seconds: 1);
print('currentTime='+DateTime.now().toString());
Timer.periodic(period, (timer) {
//到時回調
print('afterTimer='+DateTime.now().toString());
count++;
if (count >= 5) {
//取消定時器,避免無限回調
timer.cancel();
timer = null;
}
});
這裡我們的功能是每秒回調一次,當達到 5 秒後取消定時器,一共 回調了 5 次。
控制檯輸出如下:
flutter: currentTime=2019-06-08 14:16:02.906858
flutter: afterTimer=2019-06-08 14:16:03.909963
flutter: afterTimer=2019-06-08 14:16:04.910538
flutter: afterTimer=2019-06-08 14:16:05.911942
flutter: afterTimer=2019-06-08 14:16:06.911741
flutter: afterTimer=2019-06-08 14:16:07.910227
用法總結起來就是:
1.設置週期回調時間 period
2.啟動定時器 Timer.periodic(period, callback(timer))
3.處理回調 callback(timer)
4.記得在合適時機取消定時器,否則會一直回調
好了,有了上面的知識儲備,接下來,讓我們進入實戰講解環節。
實戰講解
業務場景
服務器返回一個時間,你根據服務器的時間和當前時間的對比,顯示倒計時,倒計時的時間在一天之內,超過一天顯示默認文案即可。
場景分析
這個業務場景在倒計時這一塊就需要使用到我們上面的知識了。由於限定了倒計時是在一天之內,所以顯示的文案就是從 00:00:00 到 23:59:59。
具體代碼操作
基本思路:首先我們需要獲得剩餘時間,接著啟動一個 1 秒的週期性定時器,然後每隔一秒更新一下文案。
直接上代碼:
//時間格式化,根據總秒數轉換為對應的 hh:mm:ss 格式
String constructTime(int seconds) {
int hour = seconds ~/ 3600;
int minute = seconds % 3600 ~/ 60;
int second = seconds % 60;
return formatTime(hour) + ":" + formatTime(minute) + ":" + formatTime(second);
}
//數字格式化,將 0~9 的時間轉換為 00~09
String formatTime(int timeNum) {
return timeNum < 10 ? "0" + timeNum.toString() : timeNum.toString();
}
//獲取當期時間
var now = DateTime.now();
//獲取 2 分鐘的時間間隔
var twoHours = now.add(Duration(minutes: 2)).difference(now);
//獲取總秒數,2 分鐘為 120 秒
var seconds = twoHours.inSeconds;
//設置 1 秒回調一次
const period = const Duration(seconds: 1);
//打印一開始的時間格式,為 00:02:00
print(constructTime(seconds));
Timer.periodic(period, (timer) {
//秒數減一,因為一秒回調一次
seconds--;
//打印減一後的時間
print(constructTime(seconds));
if (seconds == 0) {
//倒計時秒數為0,取消定時器
timer.cancel();
timer = null;
}
});
其實註釋也寫的很清楚了,就是基本思路的基礎上增加了一些細節處理,這裡演示是自己構造了一個兩分鐘的倒計時。
好了,基本到這裡已經說完了,但是可能 Flutter 具體一些細節還不一樣,這邊直接給下一個倒計時的完整代碼吧。
import 'dart:async';
import 'package:flutter/material.dart';
class Countdown extends StatefulWidget {
@override
_CountdownState createState() => _CountdownState();
}
class _CountdownState extends State<countdown> {
Timer _timer;
int seconds;
@override
Widget build(BuildContext context) {
return Center(
child: Text(constructTime(seconds)),
);
}
//時間格式化,根據總秒數轉換為對應的 hh:mm:ss 格式
String constructTime(int seconds) {
int hour = seconds ~/ 3600;
int minute = seconds % 3600 ~/ 60;
int second = seconds % 60;
return formatTime(hour) + ":" + formatTime(minute) + ":" + formatTime(second);
}
//數字格式化,將 0~9 的時間轉換為 00~09
String formatTime(int timeNum) {
return timeNum < 10 ? "0" + timeNum.toString() : timeNum.toString();
}
@override
void initState() {
super.initState();
//獲取當期時間
var now = DateTime.now();
//獲取 2 分鐘的時間間隔
var twoHours = now.add(Duration(minutes: 2)).difference(now);
//獲取總秒數,2 分鐘為 120 秒
seconds = twoHours.inSeconds;
startTimer();
}
void startTimer() {
//設置 1 秒回調一次
const period = const Duration(seconds: 1);
_timer = Timer.periodic(period, (timer) {
//更新界面
setState(() {
//秒數減一,因為一秒回調一次
seconds--;
});
if (seconds == 0) {
//倒計時秒數為0,取消定時器
cancelTimer();
}
});
}
void cancelTimer() {
if (_timer != null) {
_timer.cancel();
_timer = null;
}
}
@override
void dispose() {
super.dispose();
cancelTimer();
}
}
/<countdown>
效果如下:
後續打算寫一個 FlutterApp 涵蓋我之前博客的例子,方便大家結合代碼查看實際運行效果,敬請期待。
這邊之前創建了一個知識星球,歡迎互聯網小夥伴加入,一起學習,共同成長。
鏈接方式加入:
我正在「Flutter(限免)」和朋友們討論有趣的話題,你一起來吧?
https://t.zsxq.com/MVrJiAY
閱讀更多 安卓小煜 的文章