如何在Flutter中获取Otp输入框的验证码值并提交表单
如何获取自定义OTP组件的输入并提交表单(Flutter)
要实现收集4位OTP并提交表单,核心是管理多个输入框的状态,下面提供两种常用方案:
方案一:使用Form组件+onSaved回调(推荐,符合表单规范)
修改步骤:
- 将
MyHomePage改为StatefulWidget,维护表单状态和OTP值列表 - 添加
GlobalKey<FormState>管理表单,创建列表存储每个OTP输入框的值 - 修改
Otp组件,接收onSaved回调以传递输入值 - 添加提交按钮,点击时收集并拼接OTP
完整代码:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final _formKey = GlobalKey<FormState>(); List<String> _otpValues = List.filled(4, ''); void _submitForm() { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); String fullOtp = _otpValues.join(); // 替换为你的业务提交逻辑,比如发送到服务器 print('提交的验证码:$fullOtp'); // 示例:弹窗展示结果 showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('提交成功'), content: Text('你输入的验证码是:$fullOtp'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('确定'), ), ], ), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( onPressed: () {}, icon: const Icon(Icons.arrow_back_ios_new), color: Colors.black), actions: [ IconButton( onPressed: () {}, icon: const Icon(Icons.info), color: Colors.black), ], ), body: Column( children: [ const SizedBox(height: 40), const Icon(Icons.dialpad_rounded, size: 50), const SizedBox(height: 40), const Text( "Enter Mary's PIN", style: TextStyle(fontSize: 40), ), const SizedBox(height: 20), // 用Form包裹OTP输入框 Form( key: _formKey, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Otp(onSaved: (value) => _otpValues[0] = value ?? ''), Otp(onSaved: (value) => _otpValues[1] = value ?? ''), Otp(onSaved: (value) => _otpValues[2] = value ?? ''), Otp(onSaved: (value) => _otpValues[3] = value ?? ''), ], ), ), const SizedBox(height: 40), // 添加提交按钮 ElevatedButton( style: ElevatedButton.styleFrom( minimumSize: const Size(200, 50), ), onPressed: _submitForm, child: const Text('提交验证码', style: TextStyle(fontSize: 20)), ), const SizedBox(height: 20), const Text( "Rider can't find a pin", style: TextStyle(fontSize: 20), ), ], ), ); } } class Otp extends StatelessWidget { final void Function(String?)? onSaved; const Otp({ Key? key, required this.onSaved, }) : super(key: key); @override Widget build(BuildContext context) { return SizedBox( width: 50, height: 50, child: TextFormField( keyboardType: TextInputType.number, style: Theme.of(context).textTheme.headline6, textAlign: TextAlign.center, inputFormatters: [ LengthLimitingTextInputFormatter(1), FilteringTextInputFormatter.digitsOnly ], onChanged: (value) { if (value.length == 1) { FocusScope.of(context).nextFocus(); } if (value.isEmpty) { FocusScope.of(context).previousFocus(); } }, decoration: const InputDecoration( hintText: ('0'), ), // 验证输入是否为空 validator: (value) { if (value == null || value.isEmpty) { return ''; } return null; }, onSaved: onSaved, ), ); } }
方案二:使用TextEditingController(适合实时获取输入)
如果需要实时监听OTP输入状态,可以用多个TextEditingController绑定每个输入框:
核心修改:
在_MyHomePageState中创建控制器列表:
final List<TextEditingController> _otpControllers = List.generate(4, (_) => TextEditingController());
修改Otp组件接收控制器:
class Otp extends StatelessWidget { final TextEditingController controller; const Otp({ Key? key, required this.controller, }) : super(key: key); @override Widget build(BuildContext context) { return SizedBox( width: 50, height: 50, child: TextFormField( controller: controller, // 其他属性保持不变 ), ); } }
提交时拼接值:
void _submitForm() { String fullOtp = _otpControllers.map((ctrl) => ctrl.text).join(); // 处理提交逻辑 }
关键说明:
- 方案一利用Flutter表单系统,自动处理验证和保存逻辑,代码更规范
- 方案二可以实时获取每个输入框的内容,适合需要输入完成自动提交的场景
- 两种方案都能完美收集4位OTP,根据你的业务需求选择即可
内容的提问来源于stack exchange,提问作者humans9198
相关产品推荐
相关产品推荐

