首页 > 其他分享 >Flutter 短信验证码组件

Flutter 短信验证码组件

时间:2022-10-31 21:22:58浏览次数:38  
标签:count widget borderRadius 验证码 Flutter padding child 组件 final

效果图

效果图

思路

因为需要弹出键盘,所以使用了一个隐藏的 TextField,通过点击事件捕获焦点,方块只做展示使用。

组件代码

import 'package:bubble_mobile/util/func_utils.dart';
import 'package:bubble_mobile/util/size_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class VerifyCodeWidget extends StatefulWidget {
  final int count;
  final Color backgroundColor;
  final Color frontgroundColor;
  final TVoidCallback onValueChanged;
  final double aspectRatio;
  final int gapRatio;
  final bool autoFocus;
  final bool autoUnfocus;
  final double borderRadius;
  final double padding;

  VerifyCodeWidget(
      {required this.count,
      required this.backgroundColor,
      required this.frontgroundColor,
      required this.onValueChanged,
      this.aspectRatio = 1,
      this.gapRatio = 7,
      this.autoFocus = true,
      this.autoUnfocus = true,
      double? borderRadius,
      double? padding,
      super.key})
      : borderRadius = borderRadius ?? SizeUtils.blockWidth * 2,
        padding = padding ?? borderRadius ?? SizeUtils.blockWidth * 3;

  @override
  State<VerifyCodeWidget> createState() => _VerifyCodeWidgetState();
}

class _VerifyCodeWidgetState extends State<VerifyCodeWidget> {
  String _verifyCode = "";
  final FocusNode _hideInputerFocus = FocusNode();

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.topLeft,
      children: [
        Visibility(
            visible: false,
            maintainState: true,
            maintainSize: false,
            maintainAnimation: false,
            child: TextField(
              keyboardType: TextInputType.number,
              maxLength: widget.count,
              maxLengthEnforcement:
                  MaxLengthEnforcement.truncateAfterCompositionEnds,
              maxLines: 1,
              focusNode: _hideInputerFocus,
              onChanged: (v) {
                if (widget.autoUnfocus && v.length == widget.count) {
                  _hideInputerFocus.unfocus();
                }
                setState(() {
                  _verifyCode = v;
                  widget.onValueChanged.call(v);
                });
              },
            )),
        GestureDetector(
            onTap: () => _hideInputerFocus.requestFocus(),
            child: Container(
              color: widget.backgroundColor,
              child: Row(
                children: [
                  for (var i = 0; i < widget.count; ++i) ...[
                    Expanded(
                      flex: widget.gapRatio,
                      child: AspectRatio(
                          aspectRatio: widget.aspectRatio,
                          child: Container(
                            decoration: BoxDecoration(
                                color: widget.frontgroundColor,
                                borderRadius:
                                    BorderRadius.circular(widget.borderRadius)),
                            child: Padding(
                              padding: EdgeInsets.all(widget.padding),
                              child: FittedBox(
                                fit: BoxFit.fitHeight,
                                child: Text(
                                    i < _verifyCode.length
                                        ? _verifyCode[i]
                                        : "",
                                    style: TextStyle(
                                        color: widget.backgroundColor)),
                              ),
                            ),
                          )),
                    ),
                    i < widget.count - 1
                        ? Expanded(
                            flex: 1,
                            child: Container(color: Colors.transparent))
                        : Container(width: 0, color: Colors.transparent)
                  ],
                ],
              ),
            ))
      ],
    );
  }
}

组件使用

VerifyCodeWidget(
            count: 6,
            backgroundColor: ColorUtils.enableBackground,
            frontgroundColor: ColorUtils.mainTheme,
            onValueChanged: (v) => _verifyCode = v,
            autoFocus: false)

标签:count,widget,borderRadius,验证码,Flutter,padding,child,组件,final
From: https://www.cnblogs.com/seliote/p/16845842.html

相关文章

  • 微信小程序动态增加组件(以按钮为例)
    这里的微信小程序动态加载是以按钮为例,主页面点击不同的按钮进入不同的子页面中,根据主页面的title来动态加载子页面按钮的数量以及值。效果图:wxml文件(注意wx:key="item"要写......
  • React进阶篇——十二、继承方式实现高阶组件
    十二、继承方式实现高阶组件前面介绍的高阶组件的实现方式都是由高阶组件处理通用逻辑,然后将相关属性传递给被包装组件,我们称这种实现方式为属性代理。除了属性代理,还可以......
  • drf-认证组件
    views.pyfromrest_framework.responseimportResponsefromrest_framework.viewsimportAPIView#局部自定义认证逻辑classMyAutheentication(object):defau......
  • vue计算,监听属性插槽和动态组件
    计算属性如果{{函数()}},每次页面刷新,函数都会重新执行函数---》当属性来使用,缓存<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><ti......
  • java-Swing常用组件-1
    文章目录​​Swing常用组件​​Swing常用组件......
  • 移动应用开发推荐这个三方组件,时间选择即刻拥有全新体验
    TelerikUIforXamarin是一个构建跨平台移动应用程序的原生UI。TelerikUIforXamarin使用Xamarin.Forms技术,它可以让开发人员从一个单一的共享C#代码库中创建原生的iOS......
  • Zookeeper组件部署
    Zookeeper组件部署1实验目的掌握ZooKeeper集群安装部署,加深对ZooKeeper相关概念的理解,熟练ZooKeeper的一些常用Shell命令。2实验要求部署三个节点的ZooKeeper集群,通......
  • 验证码漏洞
    验证码漏洞分类图片验证码通过在图片上随机产生数字、英文字母、汉字或者问题进行验证。伴随OCR技术的发展,能够轻易被破解手机短信验证码可以比较准确和安全地保......
  • Vue组件是怎样挂载的
    我们先来关注一下$mount是实现什么功能的吧:我们打开源码路径core/instance/init.js:exportfunctioninitMixin(Vue:Class<Component>){......initLifec......
  • vue源码分析-动态组件
    前面花了两节的内容介绍了组件,从组件的原理讲到组件的应用,包括异步组件和函数式组件的实现和使用场景。众所周知,组件是贯穿整个Vue设计理念的东西,并且也是指导我们开发的......