Flutter驗證碼輸入框的2種方法實現(xiàn)
本文向您展示了在 Flutter 中實現(xiàn)完美的驗證碼輸入框幾種不同方法。
重點是什么?
真實世界的 完美的驗證碼輸入框或 PIN 輸入 UI 通常滿足以下最低要求:
- 有4個或6個文本域,每個文本域只能接受1個字符(通常是一個數(shù)字)
- 輸入數(shù)字后自動聚焦下一個字段
您經(jīng)常在需要電話號碼確認、電子郵件或雙因素身份驗證的應(yīng)用程序中看到此功能。
從頭開始制作 OTP 字段
應(yīng)用預(yù)覽
此示例創(chuàng)建一個簡單的 OTP 屏幕。首先,聚焦第一個輸入字段。當(dāng)您輸入一個數(shù)字時,光標將自動移動到下一個字段。當(dāng)按下提交按鈕時,您輸入的 OTP 代碼將顯示在屏幕上。
以下是它的工作原理:
測試此應(yīng)用程序時,您應(yīng)該使用模擬器的軟鍵盤而不是計算機的硬件鍵盤。
代碼
創(chuàng)建一個名為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); @override Widget 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); @override Widget build(BuildContext context) { return MaterialApp( // Hide the debug banner debugShowCheckedModeBanner: false, title: '堅果', theme: ThemeData( primarySwatch: Colors.indigo, ), home: const HomeScreen(), ); } } class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<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 fields final 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 widget String? _otp; @override Widget 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 fields Row( 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 code Text( _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); @override Widget 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(); } }, ), ); } }
使用第三個包
為了僅用幾行代碼快速實現(xiàn)您的目標,您可以使用第三方插件。在我們的例子中一些好的是pin_code_fields,otp_text_field等。 下面的例子將使用pin_code_fileds,它提供了很多很棒的功能:
- 自動將下一個字段集中在打字上,將上一個字段集中在委派上
- 可以設(shè)置為任意長度
- 高度可定制
- 輸入文本的 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); @override Widget build(BuildContext context) { return MaterialApp( // Hide the debug banner debugShowCheckedModeBanner: false, title: '堅果', theme: ThemeData( primarySwatch: Colors.indigo, ), home: const HomeScreen(), ); } } class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<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 fields TextEditingController textEditingController = TextEditingController(); String currentText = ""; @override Widget 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 個在 Flutter 中創(chuàng)建現(xiàn)代優(yōu)雅的 完美的驗證碼輸入框/PIN 輸入字段的示例。
到此這篇關(guān)于Flutter驗證碼輸入框的2種方法實現(xiàn)的文章就介紹到這了,更多相關(guān)Flutter驗證碼輸入框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring和IDEA不推薦使用@Autowired?注解原因解析
這篇文章主要為大家介紹了Spring和IDEA不推薦使用@Autowired?注解原因解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07why在重寫equals時還必須重寫hashcode方法分享
首先我們先來看下String類的源碼:可以發(fā)現(xiàn)String是重寫了Object類的equals方法的,并且也重寫了hashcode方法2013-10-10java調(diào)用ffmpeg實現(xiàn)視頻轉(zhuǎn)換的方法
這篇文章主要介紹了java調(diào)用ffmpeg實現(xiàn)視頻轉(zhuǎn)換的方法,較為詳細分析了java視頻格式轉(zhuǎn)換所需要的步驟及具體實現(xiàn)技巧,需要的朋友可以參考下2015-06-06SpringBoot常用計量與bean屬性校驗和進制數(shù)據(jù)轉(zhuǎn)換規(guī)則全面分析
這篇文章主要介紹了SpringBoot常用計量、bean屬性校驗與進制數(shù)據(jù)轉(zhuǎn)換規(guī)則,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10關(guān)于JSqlparser使用攻略(高效的SQL解析工具)
這篇文章主要介紹了關(guān)于JSqlparser使用攻略(高效的SQL解析工具),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11Spring中配置和讀取多個Properties文件的方式方法
本篇文章主要介紹了Spring中配置和讀取多個Properties文件的方式方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-04-04SpringBoot?SpringSecurity?JWT實現(xiàn)系統(tǒng)安全策略詳解
Spring?Security是Spring的一個核心項目,它是一個功能強大且高度可定制的認證和訪問控制框架。它提供了認證和授權(quán)功能以及抵御常見的攻擊,它已經(jīng)成為保護基于spring的應(yīng)用程序的事實標準2022-11-11