在平常開發過程當中,像倒計時這樣的場景使用的仍是比較多的,好比延時完成一段邏輯,或者在啓動頁先加載一個閃屏廣告,倒計時間到以後再進入app,更常見的場景就是咱們在獲取手機驗證碼時用於友好提示用戶的等待試圖。本次博文咱們就一塊兒來了解下基於flutter封裝一個倒計時widget的全過程java
在開始今天的博文以前,先來看下今天課程所講內容的效果圖:git
效果圖 github
從上圖咱們能夠分析得出app
1.整個過程倒計時widget一共分爲兩種狀態async
2.按鈕上的倒計時邏輯,咱們藉助dart async包下的Timer來完成ide
Timer.periodic(Duration duration, void callback(Timer timer)) 複製代碼
從方法簽名中,咱們能夠看出,Timer.periodic接收兩個參數,分別爲時間間隔,跟回調函數。咱們利用傳入時間間隔爲1秒爲週期,而後在回調函數中執行,每次時間減1的操做,若是當前剩餘時間小於1,咱們結束當前Timer,不然一直執行回調函數函數
Timer _timer;
int _countdownTime = 10;
_timer = Timer.periodic(
Duration(seconds: 1),
(Timer timer) =>
{
setState(() {
if (_countdownTime < 1) {
_timer.cancel();
} else {
_countdownTime = _countdownTime - 1;
}
})
});
複製代碼
其餘部分涉及到按鈕上狀態跟點擊事件的處理在入門進階專欄的系列文章中,我都詳細講解過,這裏就不展開細說了,讀者自行結合代碼閱讀理解吧。字體
import 'dart:async';
import 'package:flutter/material.dart';
/** * @desc * @author xiedong * @date 2020-02-28. */
class TimerCountDownWidget extends StatefulWidget {
Function onTimerFinish;
TimerCountDownWidget({this.onTimerFinish}) : super();
@override
State<StatefulWidget> createState() => TimerCountDownWidgetState();
}
class TimerCountDownWidgetState extends State<TimerCountDownWidget> {
Timer _timer;
int _countdownTime = 0;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (_countdownTime == 0) {
setState(() {
_countdownTime = 60;
});
//開始倒計時
startCountdownTimer();
}
},
child: RaisedButton(
color: Colors.black12,
child: Text(
_countdownTime > 0 ? '$_countdownTime後從新獲取' : '獲取驗證碼',
style: TextStyle(
fontSize: 14,
color: _countdownTime > 0
? Colors.white
: Color.fromARGB(255, 17, 132, 255),
),
),
),
);
}
void startCountdownTimer() {
// const oneSec = const Duration(seconds: 1);
// var callback = (timer) => {
// setState(() {
// if (_countdownTime < 1) {
// widget.onTimerFinish();
// _timer.cancel();
// } else {
// _countdownTime = _countdownTime - 1;
// }
// })
// };
//
// _timer = Timer.periodic(oneSec, callback);
_timer = Timer.periodic(
Duration(seconds: 1),
(Timer timer) => {
setState(() {
if (_countdownTime < 1) {
widget.onTimerFinish();
_timer.cancel();
} else {
_countdownTime = _countdownTime - 1;
}
})
});
}
@override
void dispose() {
super.dispose();
if (_timer != null) {
_timer.cancel();
}
}
}
複製代碼
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/pages/custom_widget/widget/timer_count_down_widget.dart';
/** * @desc * @author xiedong * @date 2020-02-28. */
class VerficationCodePage extends StatefulWidget {
@override
State<StatefulWidget> createState() => VerficationCodePageState();
}
class VerficationCodePageState extends State<VerficationCodePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("驗證碼倒計時"),
centerTitle: true,
),
body: Center(
child: TimerCountDownWidget(onTimerFinish: (){
print("倒計時結束--------");
},),
),
);
}
}
複製代碼
運行代碼後,咱們點擊獲取驗證碼按鈕,當倒計時結束後,咱們傳入的回調函數會被調用,以下圖在log控制檯打印出咱們在程序中輸入的內容:ui
本次博文相關代碼:博文源代碼this