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<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();
          }
        },
      ),
    );
  }
}

使用第三个包

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

结论

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

到此这篇关于Flutter验证码输入框的2种方法实现的文章就介绍到这了,更多相关Flutter验证码输入框内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Flutter 完美的验证码输入框实现

    老孟导读:刚开始看到这个功能的时候一定觉得so easy,开始的时候我也是这么觉得的,这还不简单,然而真正写的时候才发现并没有想象的那么简单. 先上图,不上图你们都不想看,我难啊,到Github:https://github.com/781238222/flutter-do 上给个小星星可还行,如果能fork一下,那更是感激不尽. 言归正传,完成验证码输入框经历了4个阶段,虽然前3个尝试是失败的,但也想和大家分享下,避免大家再走弯路. 第一阶段:开始的时候,我认为直接修改TextField控件,

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

    目录 重点是什么? 从头开始制作 OTP 字段 使用第三个包 结论 本文向您展示了在 Flutter 中实现完美的验证码输入框几种不同方法. 重点是什么? 真实世界的 完美的验证码输入框或 PIN 输入 UI 通常满足以下最低要求: 有4个或6个文本域,每个文本域只能接受1个字符(通常是一个数字) 输入数字后自动聚焦下一个字段 您经常在需要电话号码确认.电子邮件或双因素身份验证的应用程序中看到此功能. 从头开始制作 OTP 字段 应用预览 此示例创建一个简单的 OTP 屏幕.首先,聚焦第一个输入

  • Qt实现自定义验证码输入框控件的方法

    前言 本文实现了自定义的验证码输入框控件.控件包括图标.输入框.获取验证码按钮.验证码获取倒计时标签.支持鼠标点击获取验证码按钮后开始显示倒计时功能,倒计时为0时,才可以在此点击获取验证码按钮.效果如图: 主要的编程思想还是实现自定义控件的封装性和共用性. UI布局: 控件1:QWidget,实现整个控件的封装,这个控件使用水平布局,实现控件的水平摆放,同时,当其中一个控件隐藏时,位置会重新更新,实现在控件的后面只显示获取验证码和倒计时两个控件中的一个. 控件2:QLabel,实现展示盾牌图标.

  • Flutter组件状态管理的3种方法

    前言 前面讲了Flutter布局,布局只是静态的.在Flutter中,组件分为StatelesslWidget和StatefulWidget. StatelesslWidget 没有状态,是一成不变的.比如图标,文字,按钮等 StatefulWidget 有状态的组件,页面数据是动态的,或者会随着用户操作变化,比如多选框,文本输入框等. 有状态组件 重点来了,如何使用实现一个有状态的组件呢? 有状态的组件一般由两个类构成,一个StatefulWidget子类和一个State子类. State类包

  • Python生成随机验证码的两种方法

    使用python生成随机验证码的方法有很多种,今天小编给大家分享两种方法,大家可以灵活运用这两种方法,设计出适合自己的验证码方法. 方法一: 利用range方法,对于range方法不清楚的同学,请参考文章<python开发的range()函数> # -*- coding: utf-8 -*- import random def generate_verification_code(len=6): ''' 随机生成6位的验证码 ''' # 注意: 这里我们生成的是0-9A-Za-z的列表,当然你

  • input 标签实现输入框带提示文字效果(两种方法)

    方法一:html5配合css3实现带提示文字的输入框(摆脱js): webkit特有的一个css,可以控制里面的文字样式,配合css3的动画效果和伪类,我们就可以很容易做出一个带动画的输入框,在系统登录.搜索等位置很适合,感兴趣的你可以参考下本文或许可以帮助到你,Webkit作为载体开发系统,当然需要大量使用Html5与CSS3,不仅减少大量的JS还可以保证更流畅. 当选中对话框后,提示文字变浅色,输入后消失.这个现在通行的做法是在Input标签后面增加一个Label.使用JS控制. HTML5

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

    本文介绍了python selenium UI自动化解决验证码的4种方法,分享给大家,具体如下: 测试环境 windows7+ firefox50+ geckodriver # firefox浏览器驱动 python3 selenium3 selenium UI自动化解决验证码的4种方法:去掉验证码.设置万能码.验证码识别技术-tesseract.添加cookie登录,本次主要讲解验证码识别技术-tesseract和添加cookie登录. 1. 去掉验证码 去掉验证码,直接通过用户名和密码登陆网

  • 5种方法完美解决android软键盘挡住输入框方法详解

    在开发中,经常会遇到键盘挡住输入框的情况,比如登录界面或注册界面,弹出的软键盘把登录或注册按钮挡住了,用户必须把软键盘收起,才能点击相应按钮,这样的用户体验非常不好.像微信则直接把登录按钮做在输入框的上面,但有很多情况下,这经常满足不了需求.同时如果输入框特别多的情况下,点击输入时,当前输入框没被挡住,但是当前输入框下面的输入框却无法获取焦点,必须先把键盘收起,再去获取下面输入框焦点,这样用户体验也非常不好,那有什么办法呢?  系统的adjustResize和adjustPan有什么区别,他们使

  • Java动态验证码单线设计的两种方法

    1.java的动态验证码我这里将介绍两种方法: 一:根据java本身提供的一种验证码的写法,这种呢只限于大家了解就可以了,因为java自带的模式编写的在实际开发中是没有意义的,所以只供学习一下就可以了,待会讲解的第二种呢就是我们需要掌握的一种模式了: 第一种的代码如下: import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import

  • Java 生成图片验证码3种方法(字母、加减乘除、中文)

    第一种方法 全是字母和数字组成 package com.myFirstSpring.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import java

随机推荐