自定义View-验证码输入框

验证码输入框

1.先看下样式

在这里插入图片描述
2.直接上代码

public class MyVcode extends AppCompatEditText {
    private int mFigures = 0;// 验证码个数
    private int mCodeMargin = 0;// 验证码之间的间距
    private int mSelectColor = 0;// 选中框的颜色
    private int mNormalColor = 0;// 普通框的颜色
    private float mBorderWidth = 0f;// 边框的厚度

    Paint mNormalPaint = new Paint();
    Paint mSelectPaint = new Paint();
    Paint mOkContentPain = new Paint();//填写了内容的验证码

    private OnVerifyCodeChangedListener onVerifyCodeChangedListener;
    private int mCurrentPosition = 0;// 当前验证码的位置
    private int mEachRectLength = 0;// 矩形边长
    public MyVcode(Context context) {
        super(context, null);
    }



    public MyVcode(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttr(context,attrs);
        initPaint();
        setFocusableInTouchMode(true);
        initTextChangeListerner();
    }

    private void initTextChangeListerner() {
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                mCurrentPosition = getText().length();
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                mCurrentPosition = getText().length();
                postInvalidate();
                if (onVerifyCodeChangedListener!=null){
                    onVerifyCodeChangedListener.onVerCodeChanged(getText().toString(),start,before,count);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {
                mCurrentPosition = getText().length();
                postInvalidate();
                if (getText().length() == mFigures){
                    if (onVerifyCodeChangedListener!=null){
                        onVerifyCodeChangedListener.onInputCompleted(getText().toString());
                    }
                }else if (getText().length()>mFigures){
                    getText().delete(mFigures,getText().length());
                }
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction()==MotionEvent.ACTION_DOWN){
            requestFocus();
            setSelection(getText().length());
            showKeyBoard(getContext());
            return false;
        }

        return super.onTouchEvent(event);

    }

    private void showKeyBoard( Context context) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(this, InputMethodManager.SHOW_FORCED);
    }

    private void initAttr(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.VerifyCodeEditText);
        mFigures = ta.getInteger(R.styleable.VerifyCodeEditText_figures, 6);
        mCodeMargin = (int) ta.getDimension(R.styleable.VerifyCodeEditText_codeMargin, 0f);
        mSelectColor = ta.getColor(R.styleable.VerifyCodeEditText_selectBorderColor,getResources().getColor(R.color.base_barcolor));
        mNormalColor =
                ta.getColor(
                        R.styleable.VerifyCodeEditText_normalBorderColor,
                        getResources().getColor(android.R.color.darker_gray)
                );
        mBorderWidth = ta.getDimension(R.styleable.VerifyCodeEditText_borderWidth, 1f);

      /*  mCursorColor =
                ta.getColor(
                        R.styleable.VerifyCodeEditText_cursorColor,
                        getResources().getColor(android.R.color.darker_gray)
                );
        ta.recycle();*/

      /*  // force LTR because of bug: https://github.com/JustKiddingBaby/VercodeEditText/issues/4
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            layoutDirection = LAYOUT_DIRECTION_LTR
        }*/
    }

    private void initPaint() {
        mNormalPaint.setAntiAlias(true);
        mNormalPaint.setColor(mNormalColor);
        mNormalPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mNormalPaint.setStrokeWidth(mBorderWidth);

        mSelectPaint.setAntiAlias(true);
        mSelectPaint.setColor(mSelectColor);
        mSelectPaint.setStyle(Paint.Style.STROKE);
        mSelectPaint.setStrokeWidth(mBorderWidth);


        mOkContentPain.setAntiAlias(true);
        mOkContentPain.setColor(mSelectColor);
        mOkContentPain.setStyle(Paint.Style.FILL_AND_STROKE);
        mOkContentPain.setStrokeWidth(mBorderWidth);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        // 每个矩形的宽度  相当于我门圆的直径
        mEachRectLength = size ;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
        Editable text = this.getText();
        mCurrentPosition = text.length();
        int width = mEachRectLength -getPaddingLeft() - getPaddingRight();

        for (int i =0 ;i< mFigures;i++){
            canvas.save();
            float  start = width*i +mCodeMargin*i+mBorderWidth;
            float end = start+width - mBorderWidth;
            if (i==mFigures-1){
                end -= mBorderWidth;
            }
            RectF rect = new RectF(start, mBorderWidth, end, width - mBorderWidth);
            //画底色
            canvas.drawArc(rect, 0f, 360f, true, mNormalPaint);
            if (i == mCurrentPosition) {//选中的下一个状态
                canvas.drawArc(rect, 0f, 360f, true, mNormalPaint);
                canvas.drawArc(rect, 0f, 360f, true, mSelectPaint);
            }else {
                canvas.drawArc(rect, 0f, 360f, true, mNormalPaint);
            }

            if (mCurrentPosition>i){
                //画已经有内容的
                canvas.drawArc(rect, 0f, 360f, true, mOkContentPain);
            }
            canvas.restore();

        }
        String s = text.toString();

        //画文字
        for (int i = 0;i<mCurrentPosition;i++){
            canvas.save();
            int start = width * i + mCodeMargin * i;
            float x = start + width / 2f;
            TextPaint paint = getPaint();
            paint.setTextAlign(Paint.Align.CENTER);
            paint.setColor(getCurrentTextColor());
            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            float baseline = (width - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
            canvas.drawText(s.substring(i,i+1), x, baseline, paint);
            canvas.restore();
        }



    }

    /**
     * 验证码变化时候的监听事件
     */
    interface OnVerifyCodeChangedListener {
        /**
         * 当验证码变化的时候
         */
        public void onVerCodeChanged(String s,int start,  int before, int count);

        /**
         * 输入完毕后的回调
         */
        public void onInputCompleted(String s);
    }


}

3.自定义的属性

   <!--验证码的属性-->
    <declare-styleable name="VerifyCodeEditText">
        <attr name="figures" format="integer"/><!--验证码的个数-->
        <attr name="codeMargin" format="dimension"/><!--验证码的之间的间隔-->
        <attr name="selectBorderColor" format="color|reference"/><!--选中的边框颜色-->
        <attr name="normalBorderColor" format="color|reference"/><!--普通的边框颜色-->
        <attr name="borderWidth" format="dimension"/><!--边框的厚度 -->
        <attr name="cursorColor" format="color|reference"/><!--已经有内容的颜色 -->
    </declare-styleable>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值