Flutter 快速上手定時器倒計時及實戰講解

本文微信公眾號「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。347493flutter: 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。906858flutter: afterTimer=2019-06-08 14:16:03。909963flutter: afterTimer=2019-06-08 14:16:04。910538flutter: afterTimer=2019-06-08 14:16:05。911942flutter: afterTimer=2019-06-08 14:16:06。911741flutter: 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~09String 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:00print(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 { 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(); }}

效果如下:

Flutter 快速上手定時器/倒計時及實戰講解

後續打算寫一個 FlutterApp 涵蓋我之前部落格的例子,方便大家結合程式碼檢視實際執行效果,敬請期待。

這邊之前建立了一個知識星球,歡迎網際網路小夥伴加入,一起學習,共同成長。

連結方式加入:

我正在「Flutter(限免)」和朋友們討論有趣的話題,你一起來吧?

https://t。zsxq。com/MVrJiAY