Flutter教程六格验证码制作

我想在Flutter中实现一个六格验证码输入的功能,但遇到几个问题:

  1. 如何让输入光标在每输入一个字符后自动跳到下一个格子?
  2. 怎样限制每个格子只能输入1位数字或字母?
  3. 有没有办法在删除内容时自动跳回上一个格子?
  4. 如何添加动态的抖动效果来提示用户输入错误?
  5. 能否提供完整的代码示例,包括样式设计和交互逻辑?
  6. 对于不同屏幕尺寸,如何让验证码格子自适应宽度?
3 回复

要实现六格验证码,可以用 Flutter 的 StackPositioned 来布局六个小方块。首先创建一个状态类管理选中状态,每个方块点击时更新对应索引的状态。每个方块可以用 Container 实现,设置固定大小和边框。

  1. 创建一个列表存储六个布尔值表示是否被选中。
  2. 点击事件修改对应索引的布尔值。
  3. 通过条件渲染来改变方块的颜色:未选中是灰色,选中是蓝色。
  4. 添加动画让选中效果更自然,可以用 AnimatedContainer

完整代码如下:

class SixGridCaptcha extends StatefulWidget {
  @override
  _SixGridCaptchaState createState() => _SixGridCaptchaState();
}

class _SixGridCaptchaState extends State<SixGridCaptcha> {
  List<bool> isSelect = List.filled(6, false);

  void _onTap(int index) {
    setState(() {
      isSelect[index] = !isSelect[index];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        ...List.generate(6, (index) => Positioned(
          left: (index % 3) * 50.0,
          top: (index ~/ 3) * 50.0,
          child: GestureDetector(
            onTap: () => _onTap(index),
            child: AnimatedContainer(
              duration: Duration(milliseconds: 300),
              width: 50,
              height: 50,
              decoration: BoxDecoration(
                color: isSelect[index] ? Colors.blue : Colors.grey,
                border: Border.all(),
              ),
            ),
          ),
        )),
      ],
    );
  }
}

这样就能实现一个简单的六格验证码效果。

更多关于Flutter教程六格验证码制作的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


制作一个六格验证码的Flutter应用可以使用RowContainer来实现。首先,定义一个包含6个随机字符的字符串作为验证码。然后创建一个水平布局的Row,每个格子用一个Container表示。

代码如下:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('六格验证码')),
        body: Center(child: VerificationCode()),
      ),
    );
  }
}

class VerificationCode extends StatefulWidget {
  @override
  _VerificationCodeState createState() => _VerificationCodeState();
}

class _VerificationCodeState extends State<VerificationCode> {
  String code = generateCode();

  static String generateCode() {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
    Random rnd = Random();
    return String.fromCharCodes(Iterable.generate(6, (_) => chars[rnd.nextInt(chars.length)]));
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(6, (index) {
        return Container(
          margin: EdgeInsets.symmetric(horizontal: 5),
          width: 40,
          height: 40,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(5),
            color: Colors.blue,
          ),
          child: Center(child: Text(code[index], style: TextStyle(color: Colors.white, fontSize: 20))),
        );
      }),
    );
  }
}

这段代码会生成一个包含6个字符的验证码,并且每个字符显示在一个蓝色方块中。通过generateCode()函数生成随机验证码。

Flutter 六格验证码制作教程

在Flutter中制作六格验证码可以通过以下方法实现:

基本实现方案

import 'package:flutter/material.dart';

class VerificationCodeInput extends StatefulWidget {
  @override
  _VerificationCodeInputState createState() => _VerificationCodeInputState();
}

class _VerificationCodeInputState extends State<VerificationCodeInput> {
  List<String> _code = List.filled(6, '');
  final List<FocusNode> _focusNodes = List.generate(6, (index) => FocusNode());
  final List<TextEditingController> _controllers = List.generate(6, (index) => TextEditingController());

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(6, (index) {
        return Container(
          width: 40,
          height: 40,
          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,
              decoration: InputDecoration(
                counterText: '',
                border: InputBorder.none,
              ),
              onChanged: (value) {
                if (value.isNotEmpty && index < 5) {
                  _focusNodes[index + 1].requestFocus();
                } else if (value.isEmpty && index > 0) {
                  _focusNodes[index - 1].requestFocus();
                }
                _code[index] = value;
              },
            ),
          ),
        );
      }),
    );
  }
}

更美观的实现方案(带下划线)

class UnderlineVerificationCode extends StatelessWidget {
  final int length;
  
  UnderlineVerificationCode({this.length = 6});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(length, (index) {
        return Container(
          width: 40,
          height: 50,
          margin: EdgeInsets.symmetric(horizontal: 5),
          decoration: BoxDecoration(
            border: Border(bottom: BorderSide(color: Colors.blue, width: 2)),
          ),
          child: TextField(
            textAlign: TextAlign.center,
            keyboardType: TextInputType.number,
            maxLength: 1,
            decoration: InputDecoration(
              counterText: '',
              border: InputBorder.none,
            ),
          ),
        );
      }),
    );
  }
}

使用这些组件时,你可以通过监听输入变化来获取完整的验证码。如果需要完全隐藏输入框的样式,可以使用透明背景或其他自定义样式。

回到顶部