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

本文微信公衆號「AndroidTraveler」首發。服務器

今天給你們講講 Flutter 裏面定時器/倒計時的實現。微信

通常有兩種場景:async

  1. 我只須要你在指定時間結束後回調告訴我。回調只須要一次。
  2. 我須要你在指定時間結束後回調告訴我。回調可能屢次。

下面針對這兩種場景,咱們來講下如何在 Flutter 裏面使用。ide

回調一次的定時器

const timeout = const Duration(seconds: 5);
print('currentTime='+DateTime.now().toString());
Timer(timeout, () {
  //到時回調
  print('afterTimer='+DateTime.now().toString());
});

這裏咱們設置了超時時間爲 5 秒。而後啓動一個定時器,等到 5 秒時候到了,就會執行回調方法。學習

咱們在定時器啓動以前和以後都加上了打印日誌,控制檯打印輸出以下:ui

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.處理回調 callbackcode

回調屢次的定時器

回調屢次的定時器用法和回調一次的差很少,區別有下面兩點:orm

  1. API 調用不一樣
  2. 須要手動取消,不然會一直回調,由於是週期性的

同樣的咱們經過一個簡單的小例子來講明:blog

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();
  }

}

效果以下:

後續打算寫一個 FlutterApp 涵蓋我以前博客的例子,方便你們結合代碼查看實際運行效果,敬請期待。

這邊以前建立了一個知識星球,歡迎互聯網小夥伴加入,一塊兒學習,共同成長。
連接方式加入:
我正在「Flutter(限免)」和朋友們討論有趣的話題,你一塊兒來吧?
https://t.zsxq.com/MVrJiAY

掃碼方式加入:

相關文章
相關標籤/搜索