Flutter 完美的验证码输入框(2 种方法)

本文向您展示了在 Flutter 中实现完美的验证码输入框几种不同方法。

重点是什么?

真实世界的 完美的验证码输入框或 PIN 输入 UI 通常满足以下最低要求:

  • 有4个或6个文本域,每个文本域只能接受1个字符(通常是一个数字)
  • 输入数字后自动聚焦下一个字段

您经常在需要电话号码确认、电子邮件或双因素身份验证的应用程序中看到此功能。

从头开始制作 OTP 字段

应用预览

此示例创建一个简单的 OTP 屏幕。首先,聚焦第一个输入字段。当您输入一个数字时,光标将自动移动到下一个字段。当按下提交按钮时,您输入的 OTP 代码将显示在屏幕上。

以下是它的工作原理:

测试此应用程序时,您应该使用模拟器的软键盘而不是计算机的硬件键盘。

代码

创建一个名为OtpInput的可重用小部件:

// Create an input widget that takes only one digit
class OtpInput extends StatelessWidget {final TextEditingController controller;final bool autoFocus;const OtpInput(this.controller, this.autoFocus, {Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return SizedBox(height: 60,width: 50,child: TextField(autofocus: autoFocus,textAlign: TextAlign.center,keyboardType: TextInputType.number,controller: controller,maxLength: 1,cursorColor: Theme.of(context).primaryColor,decoration: const InputDecoration(border: OutlineInputBorder(),counterText: '',hintStyle: TextStyle(color: Colors.black, fontSize: 20.0)),onChanged: (value) {if (value.length == 1) {FocusScope.of(context).nextFocus();}},),);}
}

main.dart 中的完整源代码和解释(我将OtpInput类放在文件底部):

import 'dart:math' as math;import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:async/async.dart';
import 'package:flutter/scheduler.dart';
import 'package:url_strategy/url_strategy.dart';void main() {setPathUrlStrategy();runApp(MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(// Hide the debug bannerdebugShowCheckedModeBanner: false,title: '坚果',theme: ThemeData(primarySwatch: Colors.indigo,),home: const HomeScreen(),);}
}class HomeScreen extends StatefulWidget {const HomeScreen({Key? key}) : super(key: key);@overrideState<HomeScreen> createState() => _HomeScreenState();
}class _HomeScreenState extends State<HomeScreen> {String _imageUrl ='https://luckly007.oss-cn-beijing.aliyuncs.com/image/image-20211124085239175.png';double _fontSize = 20;String _title = "坚果公众号";// 4 text editing controllers that associate with the 4 input fieldsfinal TextEditingController _fieldOne = TextEditingController();final TextEditingController _fieldTwo = TextEditingController();final TextEditingController _fieldThree = TextEditingController();final TextEditingController _fieldFour = TextEditingController();// This is the entered code// It will be displayed in a Text widgetString? _otp;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(_title),),body: Column(mainAxisAlignment: MainAxisAlignment.center,children: [const Text('请输入验证码'),const SizedBox(height: 30,),// Implement 4 input fieldsRow(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [OtpInput(_fieldOne, true),OtpInput(_fieldTwo, false),OtpInput(_fieldThree, false),OtpInput(_fieldFour, false)],),const SizedBox(height: 30,),ElevatedButton(onPressed: () {setState(() {_otp = _fieldOne.text +_fieldTwo.text +_fieldThree.text +_fieldFour.text;});},child: const Text('提交')),const SizedBox(height: 30,),// Display the entered OTP codeText(_otp ?? '验证码',style: const TextStyle(fontSize: 30),)],),);}
}// Create an input widget that takes only one digit
class OtpInput extends StatelessWidget {final TextEditingController controller;final bool autoFocus;const OtpInput(this.controller, this.autoFocus, {Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return SizedBox(height: 60,width: 50,child: TextField(autofocus: autoFocus,textAlign: TextAlign.center,keyboardType: TextInputType.number,controller: controller,maxLength: 1,cursorColor: Theme.of(context).primaryColor,decoration: const InputDecoration(border: OutlineInputBorder(),counterText: '',hintStyle: TextStyle(color: Colors.black, fontSize: 20.0)),onChanged: (value) {if (value.length == 1) {FocusScope.of(context).nextFocus();}},),);}
}

使用第三个包

为了仅用几行代码快速实现您的目标,您可以使用第三方插件。在我们的例子中一些好的是pin_code_fields,otp_text_field等。 下面的例子将使用pin_code_fileds,它提供了很多很棒的功能:

  • 自动将下一个字段集中在打字上,将上一个字段集中在委派上
  • 可以设置为任意长度
  • 高度可定制
  • 输入文本的 3 种不同类型的动画
  • 动画活动、非活动、选定和禁用字段颜色切换
  • 自动对焦选项
  • 从剪贴板粘贴 OTP 代码

您还可以在终端窗口中看到您输入的字符:

代码

1.安装插件:

flutter pub add pin_code_fields

2.最终代码:

import 'dart:math' as math;import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:async/async.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:url_strategy/url_strategy.dart';void main() {setPathUrlStrategy();runApp(MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(// Hide the debug bannerdebugShowCheckedModeBanner: false,title: '坚果',theme: ThemeData(primarySwatch: Colors.indigo,),home: const HomeScreen(),);}
}class HomeScreen extends StatefulWidget {const HomeScreen({Key? key}) : super(key: key);@overrideState<HomeScreen> createState() => _HomeScreenState();
}class _HomeScreenState extends State<HomeScreen> {String _imageUrl ='https://luckly007.oss-cn-beijing.aliyuncs.com/image/image-20211124085239175.png';double _fontSize = 20;String _title = "坚果公众号";// 4 text editing controllers that associate with the 4 input fieldsTextEditingController textEditingController = TextEditingController();String currentText = "";@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(_title),),body: Padding(padding: const EdgeInsets.all(30),child: Center(child: PinCodeTextField(length: 6,obscureText: false,animationType: AnimationType.fade,pinTheme: PinTheme(shape: PinCodeFieldShape.box,borderRadius: BorderRadius.circular(5),fieldHeight: 50,fieldWidth: 40,activeFillColor: Colors.white,),animationDuration: const Duration(milliseconds: 300),backgroundColor: Colors.blue.shade50,enableActiveFill: true,controller: textEditingController,onCompleted: (v) {debugPrint("Completed");},onChanged: (value) {debugPrint(value);setState(() {currentText = value;});},beforeTextPaste: (text) {return true;},appContext: context,),),),);}
}

结论

我们已经介绍了 2 个在 Flutter 中创建现代优雅的 完美的验证码输入框/PIN 输入字段的示例。

关于作者:

坚果,目前是华为云享专家,51CTO 博客首席体验官,专注于大前端技术的分享,包括 Flutter,小程序,安卓,VUE,JavaScript。公众号有更多细节。

Flutter 完美的验证码输入框(2 种方法)相关推荐

  1. python selenium UI自动化解决验证码的4种方法

    测试环境 windows7+ firefox50+ geckodriver # firefox浏览器驱动 python3 selenium3 selenium UI自动化解决验证码的4种方法:去掉验证 ...

  2. Flutter实现圆形头像的几种方法

    Flutter的ClipRect的使用场景 ClipRect可以用来裁剪容器内部的子元素,以避免超出容器的范围而溢出.常见的应用场景有: 将一个图像裁剪成不同形状,如圆形.方形.椭圆等: 将一个复杂的 ...

  3. java生成验证码的三种方法

    java生成验证码的三种方法 第一种:导入jar包com.github.axet生成法 ①导包 <dependency><groupId>com.github.axet< ...

  4. python随机生成验证码_Python生成随机验证码的两种方法

    # -*- coding: utf-8 -*- import random def generate_verification_code_v2(): ''' 随机生成6位的验证码 ''' code_l ...

  5. python简单验证码识别两种方法

    既然是要简单,当然是pip一下现成库就能用的. ddddocr库 Github地址:https://github.com/sml2h3/ddddocr 谐音带带弟弟OCR,环境要求python > ...

  6. 解决flutter 依赖版本冲突的n种方法

    背景 接到一个需求,需要展示一个环状图和一个柱状图,去pub上逛了一圈,选择了功能比较全的MPFlutterChart 库.引入项目时,发现MPFlutterChart 和国际化包flutter_lo ...

  7. flutter图片实现圆形的四种方法

    flutter中可以使用Container特性.CircleAvatar的backgroundImage.ClipOval组件.ClipRRect组件实现圆角效果 1.使用Container的特性,进 ...

  8. java中获取绝对值的方法_Java完美判断绝对值的两种方法 | 彬菌

    版权声明:转载原创文章请以超链接形式请注明原文章出处,尊重作者,尊重原创! 恰饭广告 if-else语句判断: import java.util.Scanner; public class Absol ...

  9. php 短信验证登录,短信验证码注册登录的实现,php接入的3种方法(附示例)

    上周,有朋友需要帮忙做一个关于手机短信验证码注册登录的功能,之前没有做过,于是我查查资料,汇总出PHP接入短信验证码的3种方法,现在和大家分享: 1.cURL $curl = curl_init(); ...

最新文章

  1. selenium实例:unittest框架+PO开发模式
  2. Python 绘图问题:Matplotlib中plt.rcParams[]使用方法 rcsetup.py matplotlibrc
  3. UOJ#80 二分图最大权匹配 [模板题]
  4. 开机的时候重新设置密linux管理员的密码
  5. centos 7新机使用前操作
  6. 确认要从桌面删除计算机,确定要从界面上删除 我的电脑 ...
  7. Python3实现汉诺塔问题
  8. 两个条件一个为false就运行_【上古十大神马,其中一个以虎为食,一个诛杀相柳,两个龙王之子】缅怀金庸—射雕英雄传200...
  9. 《悟透JavaScript》进展汇报
  10. Flutter功能 如何给row或column布局添加手势监听?【教你一步搞定】
  11. 【T3】将“恢复记账前状态”按钮放置到工作台,一直显示。
  12. Android Glide清除缓存图片 你可能不知道
  13. This service allows sftp connections only
  14. 戴尔服务器重装系统识别不到硬盘,戴尔台式机重装系统(戴尔台式机重装系统找不到硬盘)...
  15. iPad 手指触摸与PC鼠标事件
  16. 清华大学 zhongguo li 计算机,清华大学学者发表论文列表_郭美凤
  17. 推荐引擎上策略的步骤以及查bug的方法
  18. 精读《web reflow》
  19. Linux期末考试试题长沙理工,linux操作系统考试试卷(含答案)J
  20. Stream.reduce()合并流 例BigDecimal 的add求和

热门文章

  1. 多个服务器数据互通_3月21日部分服务器数据互通公告!
  2. 一个人会python能做什么_利用Python来预测一个人有没有女朋友!无所不能!
  3. iconmobileu驱动设置教_不求人,超简单打印机共享设置!
  4. ecu故障现象_【案例】柴油电喷车维修故障案例
  5. php 正则图片相对路径替换成绝对路径_相对路径的优缺点
  6. java环境的意义_java环境变量配置的意义
  7. 服务器扫描出漏洞怎么才会被攻击_维护企业服务器安全,你需要做到这8点
  8. python查看文件夹文件的所有权限,Python判断某个用户对某个文件的权限
  9. 标签页如何用php静态显示,php使用标签替换的方式生成静态页面
  10. tkinter python 句柄_微云收藏 python tkinter.after