Flutter一次性验证码输入插件otp_input_editor的使用

Flutter一次性验证码输入插件otp_input_editor的使用

otp_input_editor 是一个用于Flutter应用的可定制的一次性密码(OTP)输入字段包。它允许用户从任何位置编辑OTP文本字段,并提供清除和隐藏功能。

特性

  • 支持自定义OTP输入字段外观。
  • 允许在输入字段内的任意位置编辑OTP。
  • 提供OTP更改的回调函数。
  • 可指定OTP长度。

安装

在你的 pubspec.yaml 文件中添加以下行:

dependencies:
  otp_input_editor: <latest-version> # 替换为最新版本

运行 flutter pub get 来安装这个包。

使用

首先导入包:

import 'package:otp_input_editor/otp_input_editor.dart';

然后在你的Flutter应用中使用 OtpInputEditor 小部件,提供必要的参数:

OtpInputEditor get _getOtpEditor {
  return OtpInputEditor(
    obscureText: !_showOtp,
    otpLength: 6,
    onOtpChanged: (value) {
      print(value);
      setState(() {
        _otpData = value;
      });
    },
    onInitialization: (OtpInputController otpInputController) {
      setState(() {
        _otpInputController = otpInputController;
      });
    },
    invalid: false,
    otpTextFieldBackgroundColor: Colors.white,
    cursorHeight: 25,
    boxShadow: const [
      BoxShadow(
        color: Colors.black12,
        blurRadius: 2.0,
        spreadRadius: 1.0,
      ),
    ],
    fieldWidth: 40.0,
    fieldHeight: 40.0,
    cursorWidth: 1.5,
    textInputStyle: const TextStyle(
      fontSize: 20.0,
      color: Colors.black,
      fontWeight: FontWeight.bold,
    ),
    boxDecoration: BoxDecoration(
      border: Border.all(
        color: Colors.grey,
        width: 1.0,
      ),
      borderRadius: BorderRadius.circular(5.0),
    ),
  );
}

参数说明

  • otpLength(必需):OTP的长度。
  • onOtpChanged(可选):当OTP发生变化时触发的回调函数。
  • invalid(可选):是否处于无效状态。
  • otpTextFieldBackgroundColor(可选):OTP输入字段的背景颜色。
  • boxShadow(可选):用于样式的阴影列表。
  • fieldWidthfieldHeight(可选):每个OTP输入字段的宽度和高度。
  • cursorWidthcursorHeight(可选):光标的宽度和高度。
  • textInputStyle(可选):文本输入的样式。
  • boxDecoration(可选):OTP输入字段的装饰。
  • obscureText(可选):是否隐藏显示输入的OTP。
  • onInitialization(可选):此回调提供了 OtpInputController,以获取更多控制权限,如清除和获取OTP字段数据。

示例代码

以下是完整的示例代码,展示了如何使用 otp_input_editor 包:

import 'package:flutter/material.dart';
import 'package:otp_input_editor/otp_input_editor.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'OTP INPUT FIELD',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(useMaterial3: true),
      home: const OtpInputField(),
    );
  }
}

class OtpInputField extends StatefulWidget {
  const OtpInputField({super.key});

  [@override](/user/override)
  State<OtpInputField> createState() => _OtpInputFieldState();
}

class _OtpInputFieldState extends State<OtpInputField> {
  String _otpData = "";
  OtpInputController? _otpInputController;
  bool _showOtp = true;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar,
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ..._getOtpText,
              _getOtpEditor,
              _spacer,
              _clearOtpButton,
              _hideOrShowButton,
            ],
          ),
        ),
      ),
    );
  }

  SizedBox get _spacer {
    return const SizedBox(height: 5);
  }

  Row get _hideOrShowButton {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        TextButton(
          onPressed: () {
            setState(() {
              _showOtp = !_showOtp;
            });
          },
          child: Row(
            children: _showOtp
                ? [
                    const Icon(Icons.visibility_off),
                    const Padding(
                      padding: EdgeInsets.symmetric(horizontal: 8),
                      child: Text("Hide"),
                    )
                  ]
                : [
                    const Icon(Icons.visibility),
                    const Padding(
                      padding: EdgeInsets.symmetric(horizontal: 8),
                      child: Text("Show"),
                    )
                  ],
          ),
        ),
      ],
    );
  }

  Row get _clearOtpButton {
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        InkWell(
          key: const Key("clear-key"),
          onTap: () {
            if (_otpInputController != null) {
              _otpInputController!.clear();
              _otpData = _otpInputController?.otp ?? "";
              setState(() {});
            }
          },
          child: const Text(
            "Clear OTP",
            style: TextStyle(
              color: Colors.blue,
              fontSize: 17,
              decoration: TextDecoration.underline,
              fontWeight: FontWeight.w500,
            ),
          ),
        ),
      ],
    );
  }

  OtpInputEditor get _getOtpEditor {
    return OtpInputEditor(
      key: const Key("otp-field"),
      obscureText: !_showOtp,
      otpLength: 6,
      onOtpChanged: (value) {
        print(value);
        setState(() {
          _otpData = value;
        });
      },
      onInitialization: (OtpInputController otpInputController) {
        setState(() {
          _otpInputController = otpInputController;
        });
      },
      invalid: false,
      otpTextFieldBackgroundColor: Colors.white,
      cursorHeight: 25,
      boxShadow: const [
        BoxShadow(
          color: Colors.black12,
          blurRadius: 2.0,
          spreadRadius: 1.0,
        ),
      ],
      fieldWidth: 40.0,
      cursorWidth: 1.5,
      textInputStyle: const TextStyle(
        fontSize: 20.0,
        color: Colors.black,
        fontWeight: FontWeight.bold,
      ),
      boxDecoration: BoxDecoration(
        border: Border.all(
          color: Colors.grey,
          width: 1.0,
        ),
        borderRadius: BorderRadius.circular(5.0),
      ),
    );
  }

  AppBar get _appBar {
    return AppBar(
      title: const Text(
        "OTP Input Editor Example",
        style: TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold,
        ),
      ),
      centerTitle: true,
    );
  }

  List<Widget> get _getOtpText {
    return [
      const Text(
        "Entered Otp:",
        style: TextStyle(
          fontSize: 25,
          fontWeight: FontWeight.bold,
        ),
      ),
      const SizedBox(height: 10),
      Text(
        key: const Key("otp-value"),
        _otpData,
        style: const TextStyle(
          fontSize: 30,
          fontWeight: FontWeight.bold,
        ),
      ),
      const SizedBox(height: 30),
    ];
  }
}

更多关于Flutter一次性验证码输入插件otp_input_editor的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter一次性验证码输入插件otp_input_editor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用otp_input_editor插件来实现一次性验证码(OTP)输入功能的示例代码。

首先,确保你已经在pubspec.yaml文件中添加了otp_input_editor依赖:

dependencies:
  flutter:
    sdk: flutter
  otp_input_editor: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中实现OTP输入界面。下面是一个完整的示例,包括导入必要的包、创建OTP输入页面,以及使用OTPInputEditor小部件。

import 'package:flutter/material.dart';
import 'package:otp_input_editor/otp_input_editor.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'OTP Input Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: OTPInputScreen(),
    );
  }
}

class OTPInputScreen extends StatefulWidget {
  @override
  _OTPInputScreenState createState() => _OTPInputScreenState();
}

class _OTPInputScreenState extends State<OTPInputScreen> {
  final List<String?> otpList = List.filled(6, null); // 6位OTP
  String? completedOTP;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OTP Input'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            OTPInputEditor(
              otpList: otpList,
              boxDecoration: BoxDecoration(
                border: Border.all(color: Colors.grey),
                borderRadius: BorderRadius.circular(8),
              ),
              boxConstraints: BoxConstraints(
                width: 200,
                height: 60,
              ),
              otpFieldStyle: TextStyle(
                fontSize: 24,
                color: Colors.black,
              ),
              otpBoxCount: 6,
              onCompleted: (otp) {
                setState(() {
                  completedOTP = otp;
                });
                print("Completed OTP: $otp");
              },
              onTextChanged: (index, value) {
                print("Index $index: $value");
              },
            ),
            SizedBox(height: 20),
            completedOTP != null
                ? Text(
                    'Completed OTP: $completedOTP',
                    style: TextStyle(fontSize: 20, color: Colors.green),
                  )
                : Container(),
          ],
        ),
      ),
    );
  }
}

代码说明

  1. 依赖导入

    • import 'package:flutter/material.dart';
    • import 'package:otp_input_editor/otp_input_editor.dart';
  2. 主应用

    • MyApp类作为应用的根组件,使用MaterialApp来设置主题和主页。
  3. OTP输入页面

    • OTPInputScreen是一个有状态的组件,包含OTP输入逻辑。
    • otpList是一个包含6个null的列表,用于存储每个OTP输入框的值。
    • completedOTP用于存储完成后的OTP值。
  4. OTP输入小部件

    • OTPInputEditor小部件用于显示OTP输入框。
    • otpList属性绑定到状态中的otpList
    • boxDecoration用于自定义输入框的外观。
    • boxConstraints设置输入框的宽度和高度。
    • otpFieldStyle用于设置输入框内文本的样式。
    • otpBoxCount设置输入框的数量(即OTP的长度)。
    • onCompleted回调在OTP输入完成时触发,并打印完成的OTP。
    • onTextChanged回调在每个输入框内容变化时触发,并打印当前输入框的索引和值。
  5. 显示完成的OTP

    • 如果completedOTP不为null,则显示完成的OTP。

运行这个示例应用,你将看到一个包含6个输入框的OTP输入界面。输入完6位数字后,OTP将自动完成,并在控制台打印出来。同时,应用界面也会显示完成的OTP。

回到顶部