前言
最近项目中有一个类似于付款的时候需要输入密码一样的控件,不过我们是输入验证码。在google上搜索了很多类似的博客,发现大部分都是通过放置多个TextView,然后放一个隐藏的EditText获取焦点的形式实现的,想着这样还不如自己撸一个控件,于是就有了这篇文章。
如何使用
通过gradle引入控件就可以使用了。1
implementation 'com.fxyan.widget:validationCodeView:1.0.2'
思考
在写之前,我们先思考一下主要需要解决的问题有哪些?
- 如何让View点击时获取到焦点并弹起数字软键盘;
- 如何监听软键盘上的输入以及删除;
如何处理
对于第一个问题,首先,我们得让View可以通过点击获取到焦点。1
2setFocusable(true);
setFocusableInTouchMode(true);
然后,我们在onTouchEvent的ACTION_DOWN事件处理中,获取焦点,并弹起输入法软键盘。1
2
3
4
5
6
7
8
9
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
requestFocus();
imm.showSoftInput(this, InputMethodManager.SHOW_FORCED);
return true;
}
return super.onTouchEvent(event);
}
最后,我们希望弹起的软键盘的输入类型是数字的。1
2
3
4
5
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
return super.onCreateInputConnection(outAttrs);
}
对于第二个问题,我们需要在View中设置KeyListener,然后处理数字输入和Del。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31private class InputKeyListener implements View.OnKeyListener {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
if (content.size() < itemCount) {
content.put(content.size(), String.valueOf(keyCode - 7));
invalidate();
if (content.size() == itemCount) {
if (onInputCompletedListener != null) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < content.size(); i++) {
builder.append(content.get(i));
}
onInputCompletedListener.onInputCompleted(builder.toString());
}
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
return true;
}
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
if (content.size() > 0) {
content.remove(content.size() - 1);
invalidate();
}
return true;
}
}
return false;
}
}
属性说明
需要注意的大致上就这两个问题,其他的东西都是结合Canvas API去绘制相应的图形和文本了。
- vcvItemCount验证码位数
- vcvItemWidth单个验证码框宽度
- vcvItemHeight单个验证码框高度
- vcvItemDistance两个验证码框之间的距离
- vcvBorderWidth验证码框的宽度
- vcvBorderStyle验证码框的样式(矩形,线)
- vcvBorderRadius框为矩形时候的圆角
- vcvContentStatus验证码的显示状态(明文,密码)
- vcvContentSize验证码为明文时的文本大小
- vcvContentRadiusWhenIsHidden验证码为密文时候的圆半径
- vcvCompletedBorderColor已填写内容的边框颜色
- vcvCompletedContentColor已填写的文本颜色
- vcvUnCompleteBorderColor未填写内容的边框颜色
- vcvIsAheadDraw是否提前渲染一个框
效果图
效果图如下