自定义验证码输入框



//实现原理,监听EditText的输入,将输入或粘贴的值画到指定位置(设置字体间距也可以这样实现);监听系统复制粘贴应该也可以,大家可以试试

public class EditTextCodeView extends androidx.appcompat.widget.AppCompatEditText {
    public Context context;
    private float wX;
    private float height;
    private float mX;
    private float rXY;
    private Paint paint,paintText,paintCursor;
    private float distance,distance2;
    private String str="";
    private boolean flag = true;
    private RectF rectF1,rectF2,rectF3,rectF4,rectF5,rectF6;
    private float clickBgWidth1,clickBgWidth2,clickBgWidth3,clickBgWidth4,clickBgWidth5,clickBgWidth6;
    private boolean initFlag=true;

    private Handler handler = new Handler(Looper.myLooper()){

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    setInvalidate();
                    break;
            }
        }
    };


    public EditTextCodeView(Context context) {
        super(context);
        this.context=context;
    }

    public EditTextCodeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context=context;
    }

    public EditTextCodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context=context;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (initFlag){
            initFlag = false;
            initData();

        }

//这里是自定义每个数字的背景,(根据需求定义自己需要的,我这里是圆角边框)
        rectF1 = new RectF(0,0,wX,height);
        canvas.drawRoundRect(rectF1,rXY,rXY,paint);

        rectF2 = new RectF(wX+mX,0,2*wX+mX,height);
        canvas.drawRoundRect(rectF2,rXY,rXY,paint);

        rectF3 = new RectF(2*wX+2*mX,0,3*wX+2*mX,height);
        canvas.drawRoundRect(rectF3,rXY,rXY,paint);

        rectF4 = new RectF(3*wX+3*mX,0,4*wX+3*mX,height);
        canvas.drawRoundRect(rectF4,rXY,rXY,paint);

        rectF5 = new RectF(4*wX+4*mX,0,5*wX+4*mX,height);
        canvas.drawRoundRect(rectF5,rXY,rXY,paint);

        rectF6 = new RectF(5*wX+5*mX,0,6*wX+5*mX,height);
        canvas.drawRoundRect(rectF6,rXY,rXY,paint);

//光标初始化(也可以不初始化)
        if (TextUtils.isEmpty(str)){
            //文字的宽度
            if (flag){
                canvas.drawText("I", rectF1.centerX(),rectF1.centerY()+ distance2,paintCursor);
                flag = false;
            }else {
                canvas.drawText("", rectF1.centerX(),rectF1.centerY()+ distance2,paintCursor);
                flag = true;
            }
        }

//画出数字
        for (int  i=0;i<str.length();i++){
            char charAt = str.charAt(i);
            switch (i){
                case 0:
                    float baseline1= rectF1.centerY()+ distance;
                    canvas.drawText(""+charAt, rectF1.centerX(),baseline1,paintText);

//判断是最后一个数字,显示光标
                    if (i==(str.length()-1)){
                        //文字的宽度
                        clickBgWidth1 = paintText.measureText(""+charAt);
                        if (flag){
                            canvas.drawText("I", rectF1.centerX()+clickBgWidth1/2+2,rectF1.centerY()+ distance2,paintCursor);
                            flag = false;
                        }else {
                            canvas.drawText("", rectF1.centerX()+clickBgWidth1/2+2,rectF1.centerY()+ distance2,paintCursor);
                            flag = true;
                        }
                    }

                    break;

                case 1:
                    float baseline2= rectF2.centerY()+ distance;
                    canvas.drawText(""+charAt, rectF2.centerX(),baseline2,paintText);
//判断是最后一个数字,显示光标
                    if (i==(str.length()-1)){
                        //文字的宽度
                        clickBgWidth2 = paintText.measureText(""+charAt);
                        if (flag){
                            canvas.drawText("I", rectF2.centerX()+clickBgWidth2/2+2,rectF2.centerY()+ distance2,paintCursor);
                            flag = false;
                        }else {
                            canvas.drawText("", rectF2.centerX()+clickBgWidth2/2+2,rectF2.centerY()+ distance2,paintCursor);
                            flag = true;
                        }
                    }
                    break;

                case 2:
                    float baseline3= rectF3.centerY()+ distance;
                    canvas.drawText(""+charAt, rectF3.centerX(),baseline3,paintText);
//判断是最后一个数字,显示光标
                    if (i==(str.length()-1)){
                        //文字的宽度
                        clickBgWidth3 = paintText.measureText(""+charAt);
                        if (flag){
                            canvas.drawText("I", rectF3.centerX()+clickBgWidth3/2+2,rectF3.centerY()+ distance2,paintCursor);
                            flag = false;
                        }else {
                            canvas.drawText("", rectF3.centerX()+clickBgWidth3/2+2,rectF3.centerY()+ distance2,paintCursor);
                            flag = true;
                        }
                    }
                    break;

                case 3:
                    float baseline4= rectF4.centerY()+ distance;
                    canvas.drawText(""+charAt, rectF4.centerX(),baseline4,paintText);
//判断是最后一个数字,显示光标
                    if (i==(str.length()-1)){
                        //文字的宽度
                        clickBgWidth4 = paintText.measureText(""+charAt);
                        if (flag){
                            canvas.drawText("I", rectF4.centerX()+clickBgWidth4/2+2,rectF4.centerY()+ distance2,paintCursor);
                            flag = false;
                        }else {
                            canvas.drawText("", rectF4.centerX()+clickBgWidth4/2+2,rectF4.centerY()+ distance2,paintCursor);
                            flag = true;
                        }
                    }
                    break;

                case 4:
                    float baseline5= rectF5.centerY()+ distance;
                    canvas.drawText(""+charAt, rectF5.centerX(),baseline5,paintText);
//判断是最后一个数字,显示光标
                    if (i==(str.length()-1)){
                        //文字的宽度
                        clickBgWidth5 = paintText.measureText(""+charAt);
                        if (flag){
                            canvas.drawText("I", rectF5.centerX()+clickBgWidth5/2+2,rectF5.centerY()+ distance2,paintCursor);
                            flag = false;
                        }else {
                            canvas.drawText("", rectF5.centerX()+clickBgWidth5/2+2,rectF5.centerY()+ distance2,paintCursor);
                            flag = true;
                        }
                    }
                    break;

                case 5:
                    float baseline6= rectF6.centerY()+ distance;
                    canvas.drawText(""+charAt, rectF6.centerX(),baseline6,paintText);
//判断是最后一个数字,显示光标
                    if (i==(str.length()-1)){
                        //文字的宽度
                        clickBgWidth6 = paintText.measureText(""+charAt);
                        if (flag){
                            canvas.drawText("I", rectF6.centerX()+clickBgWidth6/2+2,rectF6.centerY()+ distance2,paintCursor);
                            flag = false;
                        }else {
                            canvas.drawText("", rectF6.centerX()+clickBgWidth6/2+2,rectF6.centerY()+ distance2,paintCursor);
                            flag = true;
                        }
                    }
                    break;
            }
        }

        handler.removeMessages(0);
        handler.sendEmptyMessageDelayed(0,500);
    }

    private void initData() {
        paint = new Paint();
        paint.setColor(getResources().getColor(R.color.color_all));

        wX = (getWidth() - (Util.dip2px(context, 14) * 5)) / 6;//子view宽度
        mX = Util.dip2px(context, 14);//边距
        rXY = Util.dip2px(context, 4);//圆角
        height = Util.dip2px(context, 60);//高度

        paintText = new Paint();
        /*画上数字*/
        paintText.setColor(Color.BLACK);
        paintText.setTextSize(60);
        paintText.setStyle(Paint.Style.FILL);
        paintText.setTextAlign(Paint.Align.CENTER);
        //计算baseline
        Paint.FontMetrics fontMetrics=paintText.getFontMetrics();
        distance = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;


        paintCursor = new Paint();
        paintCursor.setColor(Color.BLACK);
        paintCursor.setTextSize(80);
        paintCursor.setStyle(Paint.Style.FILL);
        paintCursor.setTextAlign(Paint.Align.CENTER);
        //计算baseline
        Paint.FontMetrics fontMetrics2=paintCursor.getFontMetrics();
        distance2 = (fontMetrics2.bottom - fontMetrics2.top)/2 - fontMetrics2.bottom;


    }

    public void setOnPaintText(String str){
        this.str = str;
    }

    public void setInvalidate(){
        //更新绘制
        invalidate();
    }

    /**
     * @description 销毁
     * @param
     */
    public void setDestroy(){
        if (handler!=null){
            handler.removeCallbacksAndMessages(null);
            handler=null;
        }
    }


}



<!--布局,字体颜色和背景色一个颜色-->
<com......EditTextCodeView
            android:id="@+id/et_code_view"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_60"
            android:layout_marginTop="@dimen/dp_30"
            android:cursorVisible="false"
            android:maxLength="6"
            android:inputType="number"
            android:digits="0123456789"
            android:textColor="@color/white"
            android:background="@null"/>


//当前类调用控件和EditText的输入监听
EditTextCodeView et_code_view = view.findViewById(R.id.et_code_view);
        et_code_view.setSelection(et_code_view.length());//将光标移至文字末尾
        et_code_view.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                et_code_view.setOnPaintText(editable.toString());
                //et_code_view.setInvalidate();//刷新
            }
        });

//直接粘贴就可以使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值