Flutter 实现6个验收码输入框

开箱即用,初始化时就唤起键盘,并选中第一个

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;@overrideState<VerificationCode> createState() => _VerificationCode();
}class _VerificationCode extends State<VerificationCode> {// ... 你已有的变量Timer? _timer;int _start = 0; // 倒计时秒数(比如 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 = '';@overridevoid initState() {super.initState();_verificationController = TextEditingController();_verificationFocusNode = FocusNode();// 监听验证码输入变化_verificationController.addListener(() {setState(() {_verificationCode = _verificationController.text;});if (_verificationCode.length == 6) {_forgetPasswordPage();}});}//忘记密码void _forgetPasswordPage() async {// 验证成功后跳转页面}@overridevoid dispose() {_timer?.cancel();_verificationController.dispose();_verificationFocusNode.dispose();super.dispose();}void _handleLogin() {// TODO: 实现登录逻辑}String _getPhoneNumberLastFourDigits() {try {if (widget.phoneNumber.isEmpty) return '已发送验证码';if (!RegExp(r'^1[3-9]\d{9}$').hasMatch(widget.phoneNumber)) {return '已发送验证码';}final length = widget.phoneNumber.length;if (length >= 4) {return '已发送验证码至尾号${widget.phoneNumber.substring(length - 4)}';} else {return '已发送验证码';}} catch (_) {return '已发送验证码';}}@overrideWidget 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) // 当前输入位置:高亮蓝色: const Color.fromRGBO(227,227,227,1,), // 默认灰色边框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 计数器border: InputBorder.none,),),),// 忘记密码Container(width: double.infinity,padding: EdgeInsets.only(right: _isCounting ? 20 : 28,top: 10,),child: GestureDetector(onTap:_isCounting? null: () {// 调用你发送验证码的接口_startCountdown();},child: Text(_isCounting ? '重新获取(${_start}s)' : '重新获取',style: TextStyle(color:_isCounting? Colors.grey: const Color(0xFF4D7CFE), // 蓝色fontSize: 14,),textAlign: TextAlign.right,),),),// 后续功能组件(如登录按钮)可继续添加],),),),],),);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/84806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何查看服务器有几张GPU

要查看服务器上有多少张 GPU&#xff0c;你可以使用以下几种方法&#xff1a; 1.1 使用 nvidia-smi工具&#xff08;针对 NVIDIA GPU&#xff09;&#xff1a; 如果你的服务器上安装了 NVIDIA GPU 驱动程序&#xff0c;那么可以使用 nvidia-smi 命令查看详细的 GPU 信息。 n…

3099. 哈沙德数

​题目来源&#xff1a; LeetCode题目&#xff1a;3099. 哈沙德数 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 按要求求和判断即可。 解题代码&#xff1a; #python3 class Solution:def sumOfTheDigitsOfHarshadNumber(self, x: int) -> int:sumDigi…

数字化回归本质:第一性原理驱动的制造业转型与AI+云PLM系统实践

2014年&#xff0c;埃隆马斯克在南加州大学商学院的毕业演讲上&#xff0c;留下了一场5分钟的精彩分享&#xff0c;他将自己对工作和人生的思考总结为五个要点&#xff0c;其中一点说到了他的决策方式&#xff1a; “也许你听我说过&#xff0c;要从物理学的角度思考问题&…

仿DeepSeek AI问答系统完整版(带RAG本地知识库+联网搜索+深度思考) +springboot+vue3

今天教大家如何设计一个企业级的 deepseek问答 一样的系统 , 基于目前主流的技术&#xff1a;前端vue3&#xff0c;后端springboot。同时还带来的项目的部署教程。 系统的核心功能 1. 支持本地上传文档知识库&#xff0c;RAG技术。 支持的文档有txt&#xff0c;doc&#xff0c…

27、请求处理-【源码分析】-怎么改变默认的_method

27、请求处理-【源码分析】-怎么改变默认的_method 要改变 Spring Boot 中默认的 _method 参数&#xff0c;可以通过以下步骤实现&#xff1a; #### 原理分析 Spring Boot 中默认的 HiddenHttpMethodFilter 用于将表单中的 _method 参数值映射为实际的 HTTP 方法&#xff08;如…

欧拉角转为旋转矩阵

外旋是固定坐标系&#xff0c;内旋是动态坐标系。外旋和内旋具有等价性。 固定坐标系依次绕xyz轴旋转&#xff0c;旋转矩阵 动态坐标系依次绕zyx轴旋转&#xff0c;旋转矩阵 numpy和scipy计算对比 import numpy as np from numpy import sin, cos, pi # 抑制科学计数法&#…

【AI学习笔记】Coze平台实现生成小红书热门多图笔记

背景前摇&原视频教程&#xff1a; 最近总是在小红书上刷到多图组成的养生小妙招、效率提升小tips、退休奶奶疗愈语录等等这样的图文笔记&#xff0c;而且人物图像一眼就是AI画的。 当时我以为这个排版和文字是人工的&#xff0c;就让AI保持角色一致性画了下图&#xff0c;…

如何选择自动化编程平台

从事自动化行业的工作者都知道&#xff0c;做PLC编程需要PLC编程软件&#xff0c;做HMI可视化需要HMI编程软件&#xff0c;做SCADA需要SCADA编程软件&#xff0c;做DCS需要DCS软件&#xff0c;做仿真调试需要仿真软件。这些软件有国外的、国内的&#xff0c;有传统自动化厂商开…

Bug 背后的隐藏剧情

Bug 背后的隐藏剧情 flyfish 1. 「bug」&#xff1a;70多年前那只被拍进史书的飞蛾 故事原型&#xff1a;1947年哈佛实验室的「昆虫命案」 1947年的计算机长啥样&#xff1f;像一间教室那么大&#xff0c;塞满了几万根继电器&#xff08;类似老式开关&#xff09;&#xff…

如何将通话记录从Android传输到Android

“如何将通话记录从 Android 转移到 Android&#xff1f;我换了一部新的 Android 手机&#xff0c;想要将通话记录复制到其中。”您需要将通话记录从 Android 传输到 Android 是一种常见的情况&#xff0c;因为通话记录是手机上最重要的数据之一。幸运的是&#xff0c;如果您从…

Android 云手机横屏模式下真机键盘遮挡输入框问题处理

一、背景 打开横屏应用,点击云机EditText输入框,输入框被键盘遮挡,如下图&#xff1a; 未打开键盘状态: 点击第二个输入框,键盘遮挡了输入框&#xff1a; 二、解决方案&#xff08;推荐第三中方案,博主采用的也是第三种方案&#xff09; 博主这里整理了三种方案&#xff1a;…

进程IO之 进程

一、进程相关概念 1.什么是进程 程序&#xff1a;静态的&#xff0c;编译好的可执行文件&#xff0c;存放在磁盘中的指令和数据的集合 进程&#xff1a;动态的&#xff0c;是程序的一次执行过程&#xff0c;是独立的可调度的任务 2.进程的特点 &#xff08;1&#xff09;对…

Condition源码解读(二)

本章我们继续将Condition的最后一个方法signal方法&#xff0c;如果前面没有看过的可以点击LockSupport与Condition解析来看看Condition解读的前半部分。 signal方法&#xff1a; public final void signal() {if (!AbstractQueuedLongSynchronizer.this.isHeldExclusively())…

股票收益率的计算

首先&#xff0c;需要从 Tushare.pro 注册一个账号并调用其API获取股票日线数据&#xff08;具体操作请查看官网&#xff09;。 以通过调用tushare获取股票000001(平安银行)的股票数据为例&#xff0c;这里不设置日期&#xff0c;那么默认获取Tushare提供的所有历史数据。也可…

《算法笔记》13.2小节——专题扩展->树状数组(BIT) 问题 D: 数列-训练套题T10T3

数列(sequence.pas/c/cpp) - 问题描述 一个简单的数列问题&#xff1a;给定一个长度为n的数列&#xff0c;求这样的三个元素ai, aj, ak的个数&#xff0c;满足ai < aj > ak&#xff0c;且i < j < k。 - 输入数据 第一行是一个整数n(n < 50000)。 第二行n个整…

C# Windows Forms应用程序-001

目录 项目概述 主要组件及功能 类定义 控件声明 构造函数 Dispose 方法 InitializeComponents 方法 控件配置详解 Button 控件 (button1) TextBox 控件 (textBox1) GroupBox 控件 (groupBox1) Label 控件 (label1 至 label5) OpenFileDialog 控件 (openFileDialog1…

2025.5.28总结

今日工作&#xff1a;最近进入了项目的关键节点&#xff0c;要求每人每天提两单&#xff0c;今天周三&#xff0c;下班前只提了一个单。下午开了一场需求服务验收会&#xff0c;我演示了自己验收的那个需求&#xff0c;然后讲的不是很好。当初再构造数据时请教了一个人&#xf…

Transformer核心技术解析LCPO方法:精准控制推理长度的新突破

原创文章1FFN前馈网络与激活函数技术解析&#xff1a;Transformer模型中的关键模块2Transformer掩码技术全解析&#xff1a;分类、原理与应用场景3【大模型技术】Attention注意力机制详解一4Transformer模型中位置编码&#xff08;Positional Embedding&#xff09;技术全解析(…

在 WSL 中安装 JetBrains Toolbox:完整指南

JetBrains Toolbox 是一个非常实用的工具&#xff0c;它可以帮助开发者轻松管理 JetBrains 的各种开发工具&#xff0c;如 IntelliJ IDEA、PyCharm、WebStorm 等。通过它&#xff0c;你可以快速安装、更新和管理这些工具&#xff0c;极大地提高了开发效率。而在 WSL 环境中安装…

ZooKeeper 命令操作

文章目录 Zookeeper 数据模型Zookeeper 服务端常用命令Zookeeper 客户端常用命令 Zookeeper 数据模型 ZooKeeper 是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似&#xff0c;拥有一个层次化结构。这里面的每一个节点都被称为&#xff1a; ZNode&#xff0c;每个节…