1. 程式人生 > >Flutter佈局錦囊---驗證碼倒計時

Flutter佈局錦囊---驗證碼倒計時

設計給的效果如下:

UI佈局圖

拿到設計後,先把整體拆分成幾個部分:

  1. “獲取驗證碼按鈕”,可以通過點選按鈕來獲取驗證碼。

然後就可以開始進行編碼了。

第1步:繪製元件樹

驗證碼倒計時的元件樹

第2步:實現“獲取驗證碼按鈕”

獲取驗證碼的按鈕需要顯示在文字欄位的上面,所以你可以直接使用Flutter的墨水瓶(InkWell)元件,一個可以響應觸控的矩形區域。然後通過dart:async庫的計時器(Timer)類,使其控制墨水瓶(InkWell)元件的狀態。

import 'dart:async';
import 'package:flutter/material.dart'
; /// 墨水瓶(`InkWell`)可用時使用的字型樣式。 final TextStyle _availableStyle = TextStyle( fontSize: 16.0, color: const Color(0xFF00CACE), ); /// 墨水瓶(`InkWell`)不可用時使用的樣式。 final TextStyle _unavailableStyle = TextStyle( fontSize: 16.0, color: const Color(0xFFCCCCCC), ); class LoginFormCode extends StatefulWidget { /// 倒計時的秒數,預設60秒。
final int countdown; /// 使用者點選時的回撥函式。 final Function onTapCallback; /// 是否可以獲取驗證碼,預設為`false`。 final bool available; LoginFormCode({ this.countdown: 60, this.onTapCallback, this.available: false, }); @override _LoginFormCodeState createState() => _LoginFormCodeState(); } class
_LoginFormCodeState extends State<LoginFormCode> { /// 倒計時的計時器。 Timer _timer; /// 當前倒計時的秒數。 int _seconds; /// 當前墨水瓶(`InkWell`)的字型樣式。 TextStyle inkWellStyle = _availableStyle; /// 當前墨水瓶(`InkWell`)的文字。 String _verifyStr = '獲取驗證碼'; @override void initState() { super.initState(); _seconds = widget.countdown; } /// 啟動倒計時的計時器。 void _startTimer() { // 計時器(`Timer`)元件的定期(`periodic`)建構函式,建立一個新的重複計時器。 _timer = Timer.periodic( Duration(seconds: 1), (timer) { if (_seconds == 0) { _cancelTimer(); _seconds = widget.countdown; inkWellStyle = _availableStyle; setState(() {}); return; } _seconds--; _verifyStr = '已傳送$_seconds'+'s'; setState(() {}); if (_seconds == 0) { _verifyStr = '重新發送'; } }); } /// 取消倒計時的計時器。 void _cancelTimer() { // 計時器(`Timer`)元件的取消(`cancel`)方法,取消計時器。 _timer?.cancel(); } @override Widget build(BuildContext context) { // 墨水瓶(`InkWell`)元件,響應觸控的矩形區域。 return widget.available ? InkWell( child: Text( ' $_verifyStr ', style: inkWellStyle, ), onTap: (_seconds == widget.countdown) ? () { _startTimer(); inkWellStyle = _unavailableStyle; _verifyStr = '已傳送$_seconds'+'s'; setState(() {}); widget.onTapCallback(); } : null, ): InkWell( child: Text( ' 獲取驗證碼 ', style: _unavailableStyle, ), ); } }

第3步:還原效果

驗證碼倒計時的還原效果