Flutter 六格验证码功能开发

如何在Flutter中实现六格验证码输入功能?我需要让用户逐个输入6位数字验证码,每个数字单独显示在方格中,且输入完成后自动校验。目前遇到以下问题:

  1. 如何优雅地处理六个TextField的焦点切换?
  2. 怎样限制每个格子只能输入一个数字?
  3. 输入完成后如何自动触发验证逻辑?
  4. 是否有现成的插件可以实现这个功能,还是需要自己从头开发? 最好能提供代码示例或实现思路。
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 的 RowColumn 布局结合 Container 实现。首先创建一个包含6个 Container 的 Row,每个容器代表一个验证码格子。设置容器宽高一致,并添加边框样式。通过 GestureDetectorInkWell 为每个格子绑定点击事件,实现选中效果。

示例代码:

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');
    // 这里可以添加验证逻辑
  },
)

这个实现提供了:

  1. 六个独立的输入框
  2. 自动焦点跳转
  3. 输入完成回调
  4. 数字键盘自动弹出
  5. 美观的边框样式

你可以根据需要调整样式和交互逻辑。

回到顶部