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

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐