新手求教:如何使用Flutter实现截图所示的界面UI设计
你要实现的是多格验证码输入界面,现有代码重复声明6个TextField冗余度太高,也缺少输入自动跳转、删除回退的核心交互,优化实现逻辑如下:
以下是你需要实现的设计效果图:

优化后的实现代码
import 'package:flutter/material.dart'; class VerificationCodeInput extends StatefulWidget { // 自定义参数,可根据需求调整 final int codeLength; final double boxSize; final double borderRadius; final Color focusedBorderColor; final Color enabledBorderColor; final TextStyle textStyle; const VerificationCodeInput({ super.key, this.codeLength = 6, this.boxSize = 50, this.borderRadius = 10, this.focusedBorderColor = Colors.greenAccent, this.enabledBorderColor = Colors.grey, this.textStyle = const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black, ), }); @override State<VerificationCodeInput> createState() => _VerificationCodeInputState(); } class _VerificationCodeInputState extends State<VerificationCodeInput> { late List<FocusNode> focusNodes; late List<TextEditingController> controllers; @override void initState() { super.initState(); // 初始化每个输入框的焦点控制器和文本控制器 focusNodes = List.generate(widget.codeLength, (index) => FocusNode()); controllers = List.generate(widget.codeLength, (index) => TextEditingController()); } @override void dispose() { // 销毁控制器释放资源 for (var node in focusNodes) { node.dispose(); } for (var controller in controllers) { controller.dispose(); } super.dispose(); } @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: List.generate(widget.codeLength, (index) { return Container( width: widget.boxSize, height: widget.boxSize - 2, margin: const EdgeInsets.symmetric(horizontal: 5), child: TextField( controller: controllers[index], focusNode: focusNodes[index], style: widget.textStyle, keyboardType: TextInputType.number, // 可根据需求修改为文本键盘 textAlign: TextAlign.center, maxLength: 1, decoration: InputDecoration( counterText: "", // 隐藏输入字数统计 filled: true, fillColor: Colors.white70, contentPadding: EdgeInsets.zero, focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius)), borderSide: BorderSide(color: widget.focusedBorderColor, width: 2), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius)), borderSide: BorderSide(color: widget.enabledBorderColor, width: 1), ), ), onChanged: (value) { if (value.length == 1) { // 输入完成后自动跳转到下一个输入框 if (index < widget.codeLength - 1) { FocusScope.of(context).requestFocus(focusNodes[index + 1]); } else { // 最后一个输入框输入完成后收起键盘 focusNodes[index].unfocus(); // 这里可以添加输入完成后的回调逻辑,比如提交验证码 String fullCode = controllers.map((e) => e.text).join(); debugPrint("输入完成,验证码是:$fullCode"); } } else if (value.isEmpty) { // 内容为空时按删除跳回上一个输入框 if (index > 0) { FocusScope.of(context).requestFocus(focusNodes[index - 1]); } } }, ), ); }), ), ); } }
使用方法
直接在需要的位置引入组件即可:
// 直接使用默认配置 const VerificationCodeInput() // 自定义参数示例 VerificationCodeInput( codeLength: 4, boxSize: 60, focusedBorderColor: Colors.blue, )
核心功能说明
- 支持自定义输入框数量、尺寸、边框颜色、圆角等样式
- 输入单字符后自动跳转下一个输入框,删除时自动回退上一个输入框
- 最后一位输入完成后自动收起键盘,可直接获取完整的输入内容
- 所有控制器自动销毁,不会造成内存泄漏
内容的提问来源于stack exchange,提问作者Lakshmi n
相关产品推荐
相关产品推荐

