美文网首页Flutter
Flutter自定义Widget之验证码输入框

Flutter自定义Widget之验证码输入框

作者: 刺客的幻影 | 来源:发表于2019-07-21 13:27 被阅读0次

    实现效果

    gifhome_480x960_15s.gif

    支持属性

    属性名 效果
    cellCount 单格数量
    autofocus 是否自动聚焦
    borderRadius 单格圆角
    solidColor 单格背景色
    strokeColor 边框颜色
    textColor 字体颜色
    fontSize 字体大小
    inputCompleteCallback 输入完成的回调

    源码

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    typedef InputCompleteCallback(String content);
    
    class CellInput extends StatefulWidget {
      int cellCount = 6;
      InputType inputType = InputType.number;
      InputCompleteCallback inputCompleteCallback;
      bool autofocus = true;
      BorderRadiusGeometry borderRadius;
      Color solidColor;
      Color strokeColor;
      Color textColor;
      double fontSize;
    
      CellInput(
          {Key key,
          this.cellCount = 6,
          this.inputType,
          this.autofocus = true,
          this.inputCompleteCallback,
          this.borderRadius,
          this.solidColor,
          this.strokeColor = Colors.blue,
          this.textColor,
          this.fontSize = 22})
          : super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return _CellInputState(
            cellCount,
            inputType,
            autofocus,
            inputCompleteCallback,
            borderRadius,
            solidColor,
            strokeColor,
            textColor,
            fontSize);
      }
    }
    
    enum InputType {
      password,
      number,
      text,
    }
    
    class _CellInputState extends State<CellInput> {
      String inputStr = "";
      int _cellCount = 6;
      InputType _inputType = InputType.number;
      InputCompleteCallback _inputCompleteCallback;
      bool _autofocus = true;
      BorderRadiusGeometry _borderRadius;
      Color _solidColor;
      Color _strokeColor;
      Color _textColor;
      double _fontSize;
    
      _CellInputState(
          this._cellCount,
          this._inputType,
          this._autofocus,
          this._inputCompleteCallback,
          this._borderRadius,
          this._solidColor,
          this._strokeColor,
          this._textColor,
          this._fontSize);
    
      TextEditingController _controller = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return new Container(
          height: 48,
          child: Stack(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: getCells(),
              ),
              Container(
                height: 48,
                width: double.infinity,
                child: TextField(
                  keyboardType: _keyboardType(),
                  inputFormatters: [LengthLimitingTextInputFormatter(_cellCount)],
                  decoration: InputDecoration(border: InputBorder.none),
                  cursorWidth: 0,
                  style: TextStyle(color: Colors.transparent),
                  controller: _controller,
                  autofocus: _autofocus,
                  onChanged: (v) {
                    setState(() {
                      inputStr = v;
                      if (v.length == _cellCount) {
                        if (_inputCompleteCallback != null) {
                          _inputCompleteCallback(v);
                        }
                      }
                    });
                  },
                ),
              ),
            ],
          ),
        );
      }
    
      String getIndexStr(int index) {
        if (inputStr == null || inputStr.isEmpty) return "";
        if (inputStr.length > index) {
          if (_inputType == InputType.password) {
            return "●";
          } else {
            return inputStr[index];
          }
        } else {
          return "";
        }
      }
    
      TextInputType _keyboardType() {
        if (_inputType == InputType.number) {
          return TextInputType.number;
        } else if (_inputType == InputType.password) {
          return TextInputType.number;
        } else {
          return TextInputType.text;
        }
      }
    
      List<Widget> getCells() {
        var cells = <Widget>[];
        for (var i = 0; i < _cellCount; i++) {
          cells.add(Expanded(
            flex: 1,
            child: Center(
              child: Container(
                width: 42,
                height: 42,
                margin: EdgeInsets.only(left: 6, right: 6),
                alignment: Alignment.center,
                child: Text(
                  getIndexStr(i),
                  style: TextStyle(
                      fontSize: _fontSize,
                      color: _textColor,
                      fontWeight: FontWeight.w600),
                ),
                decoration: BoxDecoration(
                    color: _solidColor,
                    border: Border.all(width: 1, color: getBoarderColor(i)),
                    borderRadius: _borderRadius),
              ),
            ),
          ));
        }
    
        return cells;
      }
    
      Color getBoarderColor(int index) {
        if (inputStr == null || inputStr.isEmpty) {
          if (index == 0) {
            return _strokeColor;
          } else {
            return _solidColor;
          }
        } else {
          if (index == inputStr.length) {
            return _strokeColor;
          } else {
            return _solidColor;
          }
        }
      }
    }
    

    demo地址

    https://github.com/po1arbear/cell_input-flutter

    相关文章

      网友评论

        本文标题:Flutter自定义Widget之验证码输入框

        本文链接:https://www.haomeiwen.com/subject/hzvplctx.html