自定义view实现密码输入框

2020-07-05  本文已影响0人  crush_d872

最近项目中 有这样的一个需求 直接贴图了


image.png image.png

正好通过这个需求重新复习一下自定义view。

分析需求:

像这种样式,还带有输入框,那么我们第一时间想到的是继承自EditText,这个问题我们确认下来,接下来就是一些绘制的步骤了,大概讲一下绘制的一些步骤:

1.先绘制出四条线:这个主要还是根据需求走,如果你想自定义一个完美的控件,那么你可以自定义属性,在属性中自定义这个数目,然后去绘制,

2.线我们绘制好了 ,接下来其实就是把文字绘制上去了,edittext有自带的文字监听事件,我们可以通过这个事件,来把我们的文字绘制上去

3.我们看到第二张图,每次未输入的框下方的下划线 都是会变色的,所以在每次输入一个文字时 ,我们要把下一个文字框变色

需求分析完了现在我们开始动手把这个东西完善

我们自定义view主要有三个步骤:
测量、摆放,绘制
这个需求中我们应该是用不到摆放这个过程

接下来就是重点动手的时候了,建议自己先动手写一写,这样以后遇到自定义view就不虚了

1.测量

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int height = 0;
    switch (heightMode){
        case MeasureSpec.UNSPECIFIED:       //如果指定了这两种模式,就需要自己去指定高度,
        case MeasureSpec.AT_MOST:           //因为宽度是不会变化的, 至于为什么高度会变化,绘制的时候我们会讲这个
            height = sp2px(getContext(),30) + dip2px(1) + 10;
            break;
        case MeasureSpec.EXACTLY:
            height = MeasureSpec.getSize(heightMeasureSpec);
            break;
    }

    setMeasuredDimension(width,height);
}

在计算高度时,当测量模式为MeasureSpec.UNSPECIFIED,MeasureSpec.AT_MOST时,第一项计算的是文字的高度,第二项是底部横线的高度,第三项是底部横线到文字的距离,这些属性都可以自定义到属性当中,我这里就直接写数字了

2.绘制

 @Override
protected void onDraw(Canvas canvas) {
    mBottomWidth = getWidth()/4;        //底部线的长度
    for (int i=0;i<4;i++){
        int startX;
        int endX;
        //绘制底部横线的逻辑,输入第一个亮起下一个,主要是更换画笔的颜色
        startX = mBottomWidth*(i)+dip2px(5);
        endX = mBottomWidth *(1+i)-dip2px(5);
        Rect rectF = new Rect(startX,getHeight()-mBottomHeight,endX,getHeight());
        canvas.drawRect(rectF,i <= textLength ? mSelectPaint : mUnSelectPaint);
    }
    //绘制文字
    for (int i=0;i<textLength;i++){
        String child = String.valueOf(mText.charAt(i));//
        Rect rect = new Rect(mBottomWidth*i,0,mBottomWidth*(i+1),getHeight()-mBottomHeight);
        drawText(canvas,child,rect);
    }
}

private void drawText(Canvas canvas,String str,Rect rect){
    Rect mTextRect = new Rect();
    mTextPaint.getTextBounds(str,0,1,mTextRect);
    Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
    int baseline = rect.centerY()- (fontMetricsInt.top+fontMetricsInt.bottom)/2 - 10;
    canvas.drawText(str,rect.centerX()-mTextRect.width()/2,baseline,mTextPaint);
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
    this.textLength = text.length();
    this.mText = text.toString();
    invalidate();
}

还有个小问题 在我们第一次调起这个页面时,需要自动弹起键盘,

private void initPaint(){
    //自动弹出软键盘
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            setFocusable(true);
            setFocusableInTouchMode(true);
            requestFocus();
            InputMethodManager inputManager =
                    (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            inputManager.showSoftInput(PasswordEditText.this, 0);
        }
    }, 400);
    mSelectPaint = new Paint();
    mSelectPaint.setColor(getResources().getColor(R.color.color_ff345a));
    mSelectPaint.setAntiAlias(true);
    mSelectPaint.setStyle(Paint.Style.FILL);

    mUnSelectPaint = new Paint();
    mUnSelectPaint.setColor(getResources().getColor(R.color.color_e5e5e5));
    mUnSelectPaint.setAntiAlias(true);
    mUnSelectPaint.setStyle(Paint.Style.FILL);

    mTextPaint = new Paint();
    mTextPaint.setColor(getResources().getColor(R.color.color_000000));
    mTextPaint.setTextSize(sp2px(getContext(),30));
    mTextPaint.setStyle(Paint.Style.FILL);
    mTextPaint.setAntiAlias(true);
}

所以在初始化时就把这个操作做了,另外我们点击我们的自定义view时也需要调起键盘,

@Override
public boolean onTouchEvent(MotionEvent event) {
    InputMethodManager inputManager = (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.showSoftInput(this, 0);
    return super.onTouchEvent(event);
}

这样这个自定义view就结束了,很简单的自定义view,有很多细节的地方可以自己去优化,比如自定义属性等一些问题。

上一篇 下一篇

猜你喜欢

热点阅读