您当前的位置: 首页 >  android

Kevin-Dev

暂无认证

  • 0浏览

    0关注

    544博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android 自定义 View】-->验证码输入框

Kevin-Dev 发布时间:2022-05-23 14:39:06 ,浏览量:0

概述

先描述一下具体需求吧,我们在项目中可能会遇到修改用户名及密码的需求,为保证一定的完全性,服务端一般会接入短信验证码的功能。我们需要将接受到的验证码返回给服务端进行验证。可能会有以下的界面让用户输入验证码: 在这里插入图片描述

实现

1. 特性

  • 支持设置框数量
  • 支持设置框的风格样式
  • 支持根据状态区分框颜色
  • 基于EditText实现,更优雅

2. 效果图 在这里插入图片描述 3. 属性 在这里插入图片描述 4. 代码

  • attrs.xml


    
        
        
        
        
        
        
        
        
        
            
            
        
        
            
            
        
        
        

    

  • SplitEditText.java
public class SplitEditText extends AppCompatEditText {
    /**
     * 画笔
     */
    private Paint mPaint;

    /**
     * 画笔宽度
     */
    private float mStrokeWidth;

    /**
     * 边框颜色
     */
    private int mBorderColor = 0xFF666666;
    /**
     * 输入的边框颜色
     */
    private int mInputBorderColor = 0xFF1E90FF;
    /**
     * 焦点的边框颜色
     */
    private int mFocusBorderColor;

    /**
     * 框的背景颜色
     */
    private int mBoxBackgroundColor;

    /**
     * 框的圆角大小
     */
    private float mBorderCornerRadius;

    /**
     * 框与框之间的间距大小
     */
    private float mBorderSpacing;

    /**
     * 输入框宽度
     */
    private float mBoxWidth;

    /**
     * 输入框高度
     */
    private float mBoxHeight;

    /**
     * 允许输入的最大长度
     */
    private int mMaxLength = 6;

    /**
     * 文本长度
     */
    private int mTextLength;
    /**
     * 路径
     */
    private Path mPath;

    private RectF mRectF;
    private float[] mRadiusFirstArray;
    private float[] mRadiusLastArray;

    /**
     * 边框风格
     */
    private @BorderStyle int mBorderStyle = BorderStyle.BOX;

    /**
     * 边框风格
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({BorderStyle.BOX, BorderStyle.LINE})
    public @interface BorderStyle {
        /**
         * 框
         */
        int BOX = 0;
        /**
         * 线
         */
        int LINE = 1;
    }

    /**
     * 文本风格
     */
    private @TextStyle int mTextStyle = TextStyle.PLAIN_TEXT;


    /**
     * 文本风格
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({TextStyle.PLAIN_TEXT, TextStyle.CIPHER_TEXT})
    public @interface TextStyle {
        /**
         * 明文
         */
        int PLAIN_TEXT = 0;
        /**
         * 密文
         */
        int CIPHER_TEXT = 1;
    }

    /**
     * 密文掩码
     */
    private String mCipherMask;

    /**
     * 是否是粗体
     */
    private boolean isFakeBoldText;

    private static final String DEFAULT_CIPHER_MASK = "*";

    private boolean isDraw;

    private OnTextInputListener mOnTextInputListener;

    public SplitEditText(@NonNull Context context) {
        this(context,null);
    }

    public SplitEditText(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,android.R.attr.editTextStyle);
    }

    public SplitEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }


    private void init(@NonNull Context context, @Nullable AttributeSet attrs){

        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        mStrokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1f,displayMetrics);
        mBorderSpacing = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,8f,displayMetrics);
        setPadding(0,0,0,0);

        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.SplitEditText);
        final int count = a.getIndexCount();
        for (int i = 0; i  1){
            mCipherMask = mCipherMask.substring(0,1);
        }

        setBackground(null);
        setCursorVisible(false);
        setFilters(new InputFilter[]{new InputFilter.LengthFilter(mMaxLength)});
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        int width = w - getPaddingLeft() - getPaddingRight();
        int height = h - getPaddingTop() - getPaddingBottom();
        updateSizeChanged(width,height);
    }

    private void updateSizeChanged(int width,int height){
        //如果框与框之间的间距小于0或者总间距大于控件可用宽度则将间距重置为0
        if(mBorderSpacing  width){
            mBorderSpacing = 0;
        }
        //计算出每个框的宽度
        mBoxWidth = (width - (mMaxLength - 1) * mBorderSpacing) / mMaxLength - mStrokeWidth;
        mBoxHeight = height - mStrokeWidth;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //移除super.onDraw(canvas);不绘制EditText相关的
        //绘制边框
        drawBorders(canvas);
    }

    private void drawBorders(Canvas canvas){
        isDraw = true;
        //遍历绘制未输入文本的框边界
        for(int i = mTextLength; i 

    

    

    

    

	//设置监听
    splitEditText.setOnTextInputListener(new SplitEditText.OnTextInputListener(){

        @Override
        public void onTextInputChanged(String text, int length) {
            //TODO 文本输入改变
        }

        @Override
        public void onTextInputCompleted(String text) {
            //TODO 文本输入完成
        }
    });

关注
打赏
1658837700
查看更多评论
立即登录/注册

微信扫码登录

0.0584s