Flutter 六格验证码功能开发
如何在Flutter中实现六格验证码输入功能?我需要让用户逐个输入6位数字验证码,每个数字单独显示在方格中,且输入完成后自动校验。目前遇到以下问题:
- 如何优雅地处理六个TextField的焦点切换?
- 怎样限制每个格子只能输入一个数字?
- 输入完成后如何自动触发验证逻辑?
- 是否有现成的插件可以实现这个功能,还是需要自己从头开发? 最好能提供代码示例或实现思路。
3 回复
开发六格验证码功能可以这样实现:首先创建一个 Row 容器,里面包含 6 个 InkWell 或 GestureDetector 组件,每个组件代表一个验证码格子。给每个格子设置一个状态变量来跟踪是否被选中。点击时切换状态,比如改变背景颜色或文字样式。
关键代码如下:
Row(
children: List.generate(6, (index) {
return GestureDetector(
onTap: () {
setState(() {
// 切换选中状态
});
},
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
border: Border.all(),
color: isSelected(index) ? Colors.blue : Colors.grey,
),
alignment: Alignment.center,
child: Text("$index"),
),
);
}),
)
通过管理选中状态,确保用户只能选择特定数量的格子,并在完成后提交验证逻辑。注意处理样式和交互细节,比如取消已选状态等。
更多关于Flutter 六格验证码功能开发的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
开发六格验证码功能,可以用 Flutter 的 Row
和 Column
布局结合 Container
实现。首先创建一个包含6个 Container
的 Row,每个容器代表一个验证码格子。设置容器宽高一致,并添加边框样式。通过 GestureDetector
或 InkWell
为每个格子绑定点击事件,实现选中效果。
示例代码:
import 'package:flutter/material.dart';
class SixGridCaptcha extends StatefulWidget {
@override
_SixGridCaptchaState createState() => _SixGridCaptchaState();
}
class _SixGridCaptchaState extends State<SixGridCaptcha> {
List<bool> selected = List.filled(6, false);
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(6, (index) {
return GestureDetector(
onTap: () {
setState(() => selected[index] = !selected[index]);
},
child: Container(
width: 40,
height: 40,
margin: EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: selected[index] ? Colors.blue : Colors.transparent,
),
),
);
}),
);
}
}
该代码实现了基本的六格验证码交互功能,用户点击格子可切换选中状态。可根据需求进一步美化样式或增加动画效果。
Flutter 六格验证码开发
要实现一个六格验证码功能,你可以使用TextField组件配合输入格式控制。以下是实现方案:
基础实现方案
import 'package:flutter/material.dart';
class VerificationCodeInput extends StatefulWidget {
@override
_VerificationCodeInputState createState() => _VerificationCodeInputState();
}
class _VerificationCodeInputState extends State<VerificationCodeInput> {
List<String> codes = List.filled(6, '');
final List<FocusNode> focusNodes = List.generate(6, (_) => FocusNode());
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(6, (index) {
return SizedBox(
width: 40,
height: 40,
child: TextField(
focusNode: focusNodes[index],
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
maxLength: 1,
decoration: InputDecoration(
counterText: '',
border: OutlineInputBorder(),
),
onChanged: (value) {
if (value.isNotEmpty) {
codes[index] = value;
if (index < 5) {
FocusScope.of(context).requestFocus(focusNodes[index + 1]);
}
} else {
if (index > 0) {
FocusScope.of(context).requestFocus(focusNodes[index - 1]);
}
}
// 检查是否全部填写
if (!codes.contains('') && codes.length == 6) {
print('验证码: ${codes.join()}');
}
},
),
);
}),
);
}
}
更完善的实现(带样式和回调)
class VerificationCodeInput extends StatefulWidget {
final ValueChanged<String>? onCompleted;
VerificationCodeInput({this.onCompleted});
@override
_VerificationCodeInputState createState() => _VerificationCodeInputState();
}
class _VerificationCodeInputState extends State<VerificationCodeInput> {
List<String> codes = List.filled(6, '');
final List<FocusNode> focusNodes = List.generate(6, (_) => FocusNode());
final List<TextEditingController> controllers =
List.generate(6, (_) => TextEditingController());
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(6, (index) {
return Container(
width: 45,
height: 45,
margin: EdgeInsets.symmetric(horizontal: 5),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5),
),
child: Center(
child: TextField(
controller: controllers[index],
focusNode: focusNodes[index],
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
maxLength: 1,
style: TextStyle(fontSize: 20),
decoration: InputDecoration(
counterText: '',
border: InputBorder.none,
),
onChanged: (value) {
if (value.isNotEmpty) {
codes[index] = value;
if (index < 5) {
focusNodes[index + 1].requestFocus();
}
} else {
if (index > 0) {
focusNodes[index - 1].requestFocus();
}
}
if (!codes.contains('')) {
widget.onCompleted?.call(codes.join());
}
},
),
),
);
}),
);
}
}
使用方法
VerificationCodeInput(
onCompleted: (code) {
print('完整验证码: $code');
// 这里可以添加验证逻辑
},
)
这个实现提供了:
- 六个独立的输入框
- 自动焦点跳转
- 输入完成回调
- 数字键盘自动弹出
- 美观的边框样式
你可以根据需要调整样式和交互逻辑。