Flutter 實現(xiàn)6個驗收碼輸入框功能
更新時間:2025年05月30日 09:21:15 作者:Jim-zf
本文通過實例代碼給大家介紹Flutter 實現(xiàn)6個驗收碼輸入框功能,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
開箱即用,初始化時就喚起鍵盤,并選中第一個

import 'package:flutter/material.dart';
import 'dart:async'; // 引入 Timer 類
class VerificationCode extends StatefulWidget {
final String phoneNumber;
const VerificationCode({super.key, required this.phoneNumber});
static const double horizontalPadding = 28.0;
@override
State<VerificationCode> createState() => _VerificationCode();
}
class _VerificationCode extends State<VerificationCode> {
// ... 你已有的變量
Timer? _timer;
int _start = 0; // 倒計時秒數(shù)(比如 60)
bool _isCounting = false;
// 倒計時邏輯
void _startCountdown() {
setState(() {
_start = 60; // 60s 倒計時
_isCounting = true;
});
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (_start == 1) {
timer.cancel();
setState(() {
_isCounting = false;
});
} else {
setState(() {
_start--;
});
}
});
}
late TextEditingController _verificationController; // 驗證碼輸入控制器
late FocusNode _verificationFocusNode;
String _verificationCode = '';
@override
void initState() {
super.initState();
_verificationController = TextEditingController();
_verificationFocusNode = FocusNode();
// 監(jiān)聽驗證碼輸入變化
_verificationController.addListener(() {
setState(() {
_verificationCode = _verificationController.text;
});
if (_verificationCode.length == 6) {
_forgetPasswordPage();
}
});
}
//忘記密碼
void _forgetPasswordPage() async {
// 驗證成功后跳轉(zhuǎn)頁面
}
@override
void dispose() {
_timer?.cancel();
_verificationController.dispose();
_verificationFocusNode.dispose();
super.dispose();
}
void _handleLogin() {
// TODO: 實現(xiàn)登錄邏輯
}
String _getPhoneNumberLastFourDigits() {
try {
if (widget.phoneNumber.isEmpty) return '已發(fā)送驗證碼';
if (!RegExp(r'^1[3-9]\d{9}$').hasMatch(widget.phoneNumber)) {
return '已發(fā)送驗證碼';
}
final length = widget.phoneNumber.length;
if (length >= 4) {
return '已發(fā)送驗證碼至尾號${widget.phoneNumber.substring(length - 4)}';
} else {
return '已發(fā)送驗證碼';
}
} catch (_) {
return '已發(fā)送驗證碼';
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
body: Stack(
children: [
SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(
color: Colors.white,
image: DecorationImage(
image: AssetImage('assets/pageBG/backgroundLogin.png'),
fit: BoxFit.cover,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 56),
Padding(
padding: const EdgeInsets.only(left: 15),
child: SizedBox(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Image.asset(
'assets/images/return.png',
width: 20,
height: 20,
),
),
],
),
),
),
const SizedBox(height: 35),
Container(
margin: const EdgeInsets.symmetric(
horizontal: VerificationCode.horizontalPadding,
),
alignment: Alignment.centerLeft,
child: const Text(
'請輸入驗證碼',
style: TextStyle(
color: Color.fromRGBO(51, 51, 51, 1),
fontSize: 26,
fontWeight: FontWeight.w500,
),
),
),
const SizedBox(height: 6),
Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(
horizontal: VerificationCode.horizontalPadding,
),
child: Text(
_getPhoneNumberLastFourDigits(),
style: const TextStyle(
color: Color.fromRGBO(102, 102, 102, 1),
fontSize: 14,
),
),
),
const SizedBox(height: 42),
// 驗證碼輸入框
GestureDetector(
// 點擊驗證碼輸入框,使鍵盤彈出
onTap: () {
FocusScope.of(
context,
).requestFocus(_verificationFocusNode);
},
child: Container(
width: double.infinity,
height: 48,
margin: const EdgeInsets.symmetric(
horizontal: VerificationCode.horizontalPadding,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(6, (index) {
final isCurrentPosition =
_verificationCode.length == index;
final isFilled = _verificationCode.length > index;
return Container(
width: 45,
height: 48,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color:
isCurrentPosition
? const Color(0xFF4D7CFE) // 當(dāng)前輸入位置:高亮藍色
: const Color.fromRGBO(
227,
227,
227,
1,
), // 默認(rèn)灰色邊框
width: 1.5,
),
),
alignment: Alignment.center,
child: Text(
isFilled ? _verificationCode[index] : '',
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Color(0xFF333333),
),
),
);
}),
),
),
),
// 隱藏輸入框
Offstage(
offstage: true,
child: TextField(
controller: _verificationController,
focusNode: _verificationFocusNode,
keyboardType: TextInputType.number,
maxLength: 6,
autofocus: true,
decoration: const InputDecoration(
counterText: '', // 隱藏 maxLength 計數(shù)器
border: InputBorder.none,
),
),
),
// 忘記密碼
Container(
width: double.infinity,
padding: EdgeInsets.only(
right: _isCounting ? 20 : 28,
top: 10,
),
child: GestureDetector(
onTap:
_isCounting
? null
: () {
// 調(diào)用你發(fā)送驗證碼的接口
_startCountdown();
},
child: Text(
_isCounting ? '重新獲取(${_start}s)' : '重新獲取',
style: TextStyle(
color:
_isCounting
? Colors.grey
: const Color(0xFF4D7CFE), // 藍色
fontSize: 14,
),
textAlign: TextAlign.right,
),
),
),
// 后續(xù)功能組件(如登錄按鈕)可繼續(xù)添加
],
),
),
),
],
),
);
}
}到此這篇關(guān)于Flutter 實現(xiàn)6個驗收碼輸入框的文章就介紹到這了,更多相關(guān)Flutter 驗收碼輸入框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
arctext.js實現(xiàn)文字平滑彎曲弧形效果的插件
這篇文章主要介紹了arctext.js實現(xiàn)文字平滑彎曲弧形效果的插件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
JavaScript中Null與Undefined的區(qū)別解析
這篇文章主要介紹了JavaScript中Null與Undefined的區(qū)別解析,本文給出了多個代碼實例講解它們之間的區(qū)別,需要的朋友可以參考下2015-06-06
JavaScript實現(xiàn)的仿新浪微博原生態(tài)輸入字?jǐn)?shù)即時檢查功能【兼容IE6】
這篇文章主要介紹了JavaScript實現(xiàn)的仿新浪微博原生態(tài)輸入字?jǐn)?shù)即時檢查功能,涉及javascript事件響應(yīng)及字符串的遍歷、轉(zhuǎn)換、判斷等相關(guān)操作技巧,需要的朋友可以參考下2017-09-09

