Flutter 驗證碼倒計時Widget封裝

引言

在平常開發過程當中,像倒計時這樣的場景使用的仍是比較多的,好比延時完成一段邏輯,或者在啓動頁先加載一個閃屏廣告,倒計時間到以後再進入app,更常見的場景就是咱們在獲取手機驗證碼時用於友好提示用戶的等待試圖。本次博文咱們就一塊兒來了解下基於flutter封裝一個倒計時widget的全過程java

課程知識點

  • 1.關於Timer的使用
  • 2.回調函數的傳值
  • 3.組件封裝思想的創建

在開始今天的博文以前,先來看下今天課程所講內容的效果圖:git

效果圖 github

在這裏插入圖片描述

邏輯梳理

從上圖咱們能夠分析得出app

1.整個過程倒計時widget一共分爲兩種狀態async

  • 倒計時中:按照咱們設定好的時間,每次遞減一秒,直到剩餘時間爲0.在此期間按鈕字體顏色爲灰色,按鈕不可再次接收點擊事件
  • 初始狀態或完成倒計時:按鈕字體顏色爲藍色,點擊按鈕進入倒計時狀態。

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;
            }
          })
        });
            
複製代碼

其餘部分涉及到按鈕上狀態跟點擊事件的處理在入門進階專欄的系列文章中,我都詳細講解過,這裏就不展開細說了,讀者自行結合代碼閱讀理解吧。字體

封裝好的倒計時Widget代碼:
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();
    }
  }
}

複製代碼
在頁面中做爲Widget使用
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

相關文章
相關標籤/搜索