Android自定义数字验证码输入框

先上效果图

效果图

设计思路

刚开始想过使用EditText来实现,但是具体实施时发现并不是这么容易,而且还有一堆的坑,不如直接继承View自定义来的方便,先在onDraw方法中绘制边框及验证码,调整弹出输入法只能输入数字,监听输入法输入,每输入一个字符都需要重新绘制,另外考虑到扩展性需要重写onMeasure方法来计算View的大小。

具体实现

首先需要在onDraw中绘制外面带有圆角的矩形边框以及数字中间的分割线。

/**
 * 绘制边框及分割线
 *
 * @param canvas
 */
private void drawFrame(Canvas canvas) {
    RectF oval = new RectF(padding,
            padding,
            getWidth() - padding,
            getHeight() - padding);
    canvas.drawRoundRect(oval, 10, 10, boxPaint);

    for (int i = 1; i < count; i++) {
        canvas.drawLine(padding + boxSize * i,
                padding,
                padding + boxSize * i,
                padding + boxSize,
                boxPaint);
    }
}

然后再绘制数字验证码,每当输入或删除文本时都需要调用invalidate()方法重新绘制一遍:

Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float fontHeight = fontMetrics.bottom - fontMetrics.top;
    if (textBaseY == 0)
textBaseY = getHeight() - (getHeight() - fontHeight) / 2 - fontMetrics.bottom;
int y = (int) textBaseY;

    if (!TextUtils.isEmpty(currentNumber)) {
    if (currentNumber.length() > count) {
        currentNumber.delete(count, currentNumber.length() - 1);
    }
    for (int i = 0; i < currentNumber.length(); i++) {
        canvas.drawText("" + currentNumber.charAt(i),
                padding + boxSize * i + (boxSize / 2),
                y,
                textPaint);
    }
}

这里需要设置弹出的输入法只能输入数字,如下:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;//定义软键盘样式为数字键盘
    return super.onCreateInputConnection(outAttrs);
}

弹出软键盘之后监听按键输入:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    //接收按键事件,67是删除键(backspace),7-16就是0-9
    if (keyCode == 67 && currentNumber.length() > 0) {
        currentNumber.deleteCharAt(currentNumber.length() - 1);
        //重新绘制
        invalidate();
    } else if (keyCode >= 7 && keyCode <= 16 && currentNumber.length() < count) {
        currentNumber.append(keyCode - 7);
        invalidate();
    }
    return super.onKeyDown(keyCode, event);
}

下面连个方法是打开输入法和关闭输入法,可以设置初始时打开输入法:

/**
 * 打开输入法
 */
private void showInputMethod() {
    postDelayed(new Runnable() {
        @Override
        public void run() {
            inputMethodManager.viewClicked(NumberInputView.this);
            inputMethodManager.showSoftInput(NumberInputView.this,
                    InputMethodManager.SHOW_FORCED);
        }
    }, 100);
}

/**
 * 关闭输入法
 */
private void closeInputMethod() {
    post(new Runnable() {
        @Override
        public void run() {
            if (inputMethodManager.isActive()) {
                inputMethodManager.hideSoftInputFromInputMethod(NumberInputView.this.getWindowToken(),
                        0);
            }
        }
    });
}

这里只是把几个主要的地方发上来,下面放上源码连接:
https://github.com/0xZhangKe/Collection/tree/master/NumberInputView

猜你喜欢

转载自blog.csdn.net/u013872857/article/details/69563413