先上效果图
刚开始想过使用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