Flutter验证码输入框的2种方法实现

网友投稿 314 2022-11-12

Flutter验证码输入框的2种方法实现

目录重点是什么?从头开始制作 OTP 字段使用第三个包结论

本文向您展示了在 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);

@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 createState() => _HomeScreenState();

}

class _HomeScreenState extends State {

String _imageUrl =

'https://luckly007.oss-cn-beijing.aliyuncs.com/image/image-20211124085239175.png';

double _fontSize = 20;

// 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();

}

},

),

);

}

}

使用第三个包

为了仅用几行代码快速实现您的目标,您可以使用第三方插件。在我们的例子中一些好的是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}) : supehttp://r(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 createState() => _HomeScreenState();

}

class _HomeScreenState extends State {

String _imageUrl =

'https://luckly007.oss-cn-beijing.aliyuncs.com/image/image-20211124085239175.png';

double _fontSize = 20;

// 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,

),

),

),

);

}

}

结论

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:5分钟Serverless实践 | 构建无服务器图片鉴黄Web应用
下一篇:MySQL-JDBC Loadbalance深入解析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~