我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

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

重点是什么?

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

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

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

从头开始制作 OTP 字段

应用预览

image-20211220134159049

此示例创建一个简单的 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,它提供了很多很棒的功能:

image-20211220134456679

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

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

img

代码

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验证码输入框内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Flutter验证码输入框的实现方法有哪些

Flutter验证码输入框的实现方法有哪些,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。重点是什么?真实世界的 完美的验证码输入框或 PIN 输入 UI 通常满
2023-06-22

uniapp手机验证码输入框如何实现

本篇内容主要讲解“uniapp手机验证码输入框如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“uniapp手机验证码输入框如何实现”吧!如键盘被隐藏,可直接点击蓝框弹出键盘,蓝框就相当于i
2023-07-05

uniapp自定义输入框,实现验证码输入框、密码输入框、兼容微信小程序

前言 在移动端或者小程序项目中,验证码输入框、密码输入框也是很常见的,今天我们就来实现一个这样的效果。 图片展示 代码实现 我这里是用uniapp实现的可兼容微信小程序。 大家如果需要微信小程序也可以参考此案例,实现思路都是一样的。 te
2023-08-18

如何使用Android实现常见的验证码输入框

小编给大家分享一下如何使用Android实现常见的验证码输入框,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!正文先搂一眼效果吧不要把注意力都放在头顶的那一抹绿上,
2023-05-30

Android实现自定义验证码输入框效果(实例代码)

这里提一下,这个当时也是在网上看到一个博主写的代码改了下用在我么项目中的验证码输入框。博主的地址不记得了这里只能顺带标注一下。。。 效果图如下:就是这个酱紫 直入主题,代码如下: xml布局:
2022-06-06

详解iOS 验证码输入的实现思路

如图所示,现在很多App采用了类似下划线、方块等方式的验证码输入,直观美观!对于这种效果的实现方式,大概有以下几种方式: 1.多个UITextField组成 这种方式好处是有光标闪烁、但是在处理删除和动画效果时,就会显得有点笨拙,OFO应该
2022-05-23

Android实现验证码登录的方法

这篇文章主要介绍了Android实现验证码登录的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。结果展示1.导包1.1在项目的gradle中导入maven { url "h
2023-06-14

php手机验证码实现的方法

这篇文章主要介绍“php手机验证码实现的方法”,在日常操作中,相信很多人在php手机验证码实现的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php手机验证码实现的方法”的疑惑有所帮助!接下来,请跟着小编
2023-06-07

Android实现IP地址输入框的方法示例代码

前言本文主要给大家介绍了关于Android实现IP地址格式输入框的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。实现效果图:解决方案: 1.添加4个EditText和三个TextView 2.
2023-05-30

Android获取短信验证码的实现方法

先给大家展示下效果图,如果感觉不错,请参考实现思路详解Android开发中关于短息验证码的设计层出不穷,越来越多的应用为了更好的提高软件的安全性,开始使用通过服务器向用户发送验证码的方式,来保护用户个人信息的安全性。无论是用户注册时的信息验
2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录