Android自定義數字驗證碼輸入框
阿新 • • 發佈:2019-01-05
先上效果圖
設計思路
剛開始想過使用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);
}
}
});
}