Flutter 完美的验证码输入框(2 种方法)
Flutter 完美的驗(yàn)證碼輸入框(2 種方法)
本文向您展示了在 Flutter 中實(shí)現(xiàn)完美的驗(yàn)證碼輸入框幾種不同方法。
重點(diǎn)是什么?
真實(shí)世界的 完美的驗(yàn)證碼輸入框或 PIN 輸入 UI 通常滿足以下最低要求:
- 有4個(gè)或6個(gè)文本域,每個(gè)文本域只能接受1個(gè)字符(通常是一個(gè)數(shù)字)
- 輸入數(shù)字后自動(dòng)聚焦下一個(gè)字段
您經(jīng)常在需要電話號(hào)碼確認(rèn)、電子郵件或雙因素身份驗(yàn)證的應(yīng)用程序中看到此功能。
從頭開(kāi)始制作 OTP 字段
應(yīng)用預(yù)覽
此示例創(chuàng)建一個(gè)簡(jiǎn)單的 OTP 屏幕。首先,聚焦第一個(gè)輸入字段。當(dāng)您輸入一個(gè)數(shù)字時(shí),光標(biāo)將自動(dòng)移動(dòng)到下一個(gè)字段。當(dāng)按下提交按鈕時(shí),您輸入的 OTP 代碼將顯示在屏幕上。
以下是它的工作原理:
測(cè)試此應(yīng)用程序時(shí),您應(yīng)該使用模擬器的軟鍵盤(pán)而不是計(jì)算機(jī)的硬件鍵盤(pán)。
代碼
創(chuàng)建一個(gè)名為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: '堅(jiān)果',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 = "堅(jiān)果公眾號(hào)";// 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('請(qǐng)輸入驗(yàn)證碼'),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 ?? '驗(yàn)證碼',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();}},),);} }使用第三個(gè)包
為了僅用幾行代碼快速實(shí)現(xiàn)您的目標(biāo),您可以使用第三方插件。在我們的例子中一些好的是pin_code_fields,otp_text_field等。 下面的例子將使用pin_code_fileds,它提供了很多很棒的功能:
- 自動(dòng)將下一個(gè)字段集中在打字上,將上一個(gè)字段集中在委派上
- 可以設(shè)置為任意長(zhǎng)度
- 高度可定制
- 輸入文本的 3 種不同類型的動(dòng)畫(huà)
- 動(dòng)畫(huà)活動(dòng)、非活動(dòng)、選定和禁用字段顏色切換
- 自動(dòng)對(duì)焦選項(xiàng)
- 從剪貼板粘貼 OTP 代碼
您還可以在終端窗口中看到您輸入的字符:
代碼
1.安裝插件:
flutter pub add pin_code_fields2.最終代碼:
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: '堅(jiān)果',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 = "堅(jiān)果公眾號(hào)";// 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,),),),);} }結(jié)論
我們已經(jīng)介紹了 2 個(gè)在 Flutter 中創(chuàng)建現(xiàn)代優(yōu)雅的 完美的驗(yàn)證碼輸入框/PIN 輸入字段的示例。
關(guān)于作者:
堅(jiān)果,目前是華為云享專家,51CTO 博客首席體驗(yàn)官,專注于大前端技術(shù)的分享,包括 Flutter,小程序,安卓,VUE,JavaScript。公眾號(hào)有更多細(xì)節(jié)。
總結(jié)
以上是生活随笔為你收集整理的Flutter 完美的验证码输入框(2 种方法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: RecyclerView高级控件-附实例
- 下一篇: 电子书网站推荐(收藏系列)