阅读 120

flutter 自定义验证码输入框实现 verification_code_custom

码一个验证码的输入框,实现效果如下:

example.gif

实现思路

1.选用控件:TextField

这里选择使用4/6个TextField,隐藏光标,设置TextField样式

      decoration: InputDecoration(
        hintStyle: TextStyle(color: Color(0xff8C8C8C), fontSize: 14),
        focusedBorder: UnderlineInputBorder(
            borderSide: BorderSide(color: Color(0xFFFD3B60), width: 1)),
        enabledBorder: UnderlineInputBorder(
            borderSide: BorderSide(color: Color(0xffDADADA), width: 1)),
        fillColor: Colors.transparent,
        filled: true,
      )
复制代码

存储数据使用两个list,一个存储值,一个存储焦点

  List<FocusNode> focusNodeList = [];
  List<String> textList = [];
复制代码

2.处理焦点跳转逻辑

输入完一个字符后跳转到下一个TextField,最后一个输入完成后失去焦点,收起键盘

onChanged: (value) {
         ...
          textList[index] = value;
          //焦点后移
          if (index < focusNodeList.length - 1) {
            _getFocus(focusNodeList[index + 1]);
            textList[index + 1] = ' ';
          } else {
            _loseFocus(focusNodeList[index]);
          }
          setState(() {});
          textChanged(textList);
      ...
      },
复制代码

3.处理复制验证码逻辑

当检测输入为粘贴的数据时,直接填充

 //输入值为复制的验证码
        //输入值为复制的验证码
        if (value.length == itemCount || value.length == itemCount + 1) {
          if (value.length == itemCount + 1) {
            if (oldStr == value.substring(0, 1)) {
              //删除第一位
              value = value.substring(1);
            } else {
              //删除最后一位
              value = value.substring(0, value.length - 1);
            }
          }

          //所有重新赋值
          for (int i = 0; i < textList.length; i++) {
            textList[i] = value.substring(i, i + 1);
          }
          _loseFocus(focusNodeList[index]);
          setState(() {});
          textChanged(textList);
          return;
        }
复制代码

4.处理删除按键逻辑

TextField获取焦点没有值时,按删除按钮onChanged方法是没有响应的,我这里的处理方式是在焦点跳转到下一个输入框的时候先插入一个空白字符,用以捕获删除按钮点击。

textList[i + 1] = ' ';
复制代码

5.禁用可选事件

到这里基本实现了点击效果,但是产品出不能让用户自由选择单个输入框,只能是依次输入或者依次删除。 这里我在输入框上面盖了一个透明的View,然后处理它的点击事件

 GestureDetector(
            onTap: () {
              for (int i = textList.length - 1; i >= 0; i--) {
                String text = textList[i];

                if ((text.length > 0 && text != ' ') || i == 0) {
                  if (i < textList.length - 1 && i != 0) {
                    _getFocus(focusNodeList[i + 1]);
                    if (textList[i + 1].length == 0) {
                      textList[i + 1] = ' ';
                    }
                  } else if (i == textList.length - 1) {
                    _getFocus(focusNodeList[i]);
                  } else {
                      _getFocus(focusNodeList[0]);
                  }
                  break;
                }
              }
            },
复制代码

还有一些需求比如方形框选择,这里就没有添加了,后续可能用到的时候会添加接口,需要的话可以拉下来改一下源码就好

仓库地址:verification_code_custom

文章分类
前端
文章标签