android edittext_Android 验证码输入框的实现
黑客技术点击右侧关注,了解黑客的世界!Linux编程点击右侧关注,免费入门到精通!作者丨实例波https://www.jianshu.com/p/3238a5afc21c前言验证码输入框是很多APP必不可少的组件,之前在重构注册登录页面的时候,重新设计了UI,所以不能再简单的用EditText来做了,所以这篇文章将分享一下如何实现一个常见的验证码输入框。正文先搂一眼效果吧不要把注意力都放...
作者丨实例波
https://www.jianshu.com/p/3238a5afc21c
前言
验证码输入框是很多APP必不可少的组件,之前在重构注册登录页面的时候,重新设计了UI,所以不能再简单的用EditText来做了,所以这篇文章将分享一下如何实现一个常见的验证码输入框。
正文
先搂一眼效果吧
不要把注意力都放在头顶的那一抹绿上,重点在输入框,可能大多数APP里都是采用6个方框的UI效果,我这里是按照我们设计的要求,用6根横线来划出6个数字的位置。一开始我想的是直接用6个TextView,然后传递焦点的做法,但是发现实现起来有一定的难度。又在网上查了一下,发现比较靠谱的办法是用6个TextView加一个EditText来实现,也按照这个方法去实现了,但是后来在测试的时候就发现了问题:网上给出的实现方式需要监听软键盘的删除按钮
editText.setOnKeyListener(new OnKeyListener() {
@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN) {//TODO:return true;
}return false;
}
});
这是一个大家熟知的写法,但是这个监听的方法其实并不靠谱(在安卓原生键盘上就监听不到),因为这个监听是否触发,并没有强制的要求,全看输入法开发者的心情,这是官方文档中的描述:
Key presses in software keyboards will generally NOT trigger this method, although some may elect to do so in some situations.
只能输入,不能删除,这可不行啊,用户肯定会骂娘的,我可不想被拿去去祭天什么的…
于是乎只能想办法在原有的基础上做一些修改,来规避这个问题,最后采用的方案是:采用一个TextView的数组来维护6个TextView,然后藏一个透明的EditTextView在后面用于接收用户输入的内容,再把输入的内容展示到6个TextView上就行了,UI什么的可以自己随意设计。在实现的过程中,遇到的一个关键问题就是:当输入的内容超过6位以后我该如何处理?一开始的方案是通过判断当前输入的位数然后再做相应的处理,网上的方案也是这么实现的,我后来一想,根本用不着这么麻烦,只需要一行属性就能解决这个问题:
android:maxLength="6"
只需要在EditText的属性里限制它的最大长度,就不用再去代码里做处理了,直接把EditTextView里的内容完全照搬到TextView上就可以了。
最终的完整代码如下:
public class VerifyCodeView extends RelativeLayout {private EditText editText;private TextView[] textViews;private static int MAX = 6;private String inputContent;public VerifyCodeView(Context context) {this(context, null);
}public VerifyCodeView(Context context, AttributeSet attrs) {this(context, attrs, 0);
}public VerifyCodeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);
View.inflate(context, R.layout.view_verify_code, this);
textViews = new TextView[MAX];
textViews[0] = (TextView) findViewById(R.id.tv_0);
textViews[1] = (TextView) findViewById(R.id.tv_1);
textViews[2] = (TextView) findViewById(R.id.tv_2);
textViews[3] = (TextView) findViewById(R.id.tv_3);
textViews[4] = (TextView) findViewById(R.id.tv_4);
textViews[5] = (TextView) findViewById(R.id.tv_5);
editText = (EditText) findViewById(R.id.edit_text_view);
editText.setCursorVisible(false);//隐藏光标
setEditTextListener();
}private void setEditTextListener() {
editText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}@Overridepublic void afterTextChanged(Editable editable) {
inputContent = editText.getText().toString();if (inputCompleteListener != null) {if (inputContent.length() >= MAX) {
inputCompleteListener.inputComplete();
} else {
inputCompleteListener.invalidContent();
}
}for (int i = 0; i if (i textViews[i].setText(String.valueOf(inputContent.charAt(i)));
} else {
textViews[i].setText("");
}
}
}
});
}private InputCompleteListener inputCompleteListener;public void setInputCompleteListener(InputCompleteListener inputCompleteListener) {this.inputCompleteListener = inputCompleteListener;
}public interface InputCompleteListener {void inputComplete();void invalidContent();
}public String getEditContent() {return inputContent;
}
}
经过thisfeng的提醒,发现存在几个问题:
1.双击和长按会选中EditText的内容,出现复制粘贴等选项
2.光标位置会随着点击而改变,输入数字可能会插入到中间的位置
于是做了相应的修改:
//屏蔽长按事件
android:longClickable="false"
使用自定义EditText:public class MyEditText extends AppCompatEditText {private long lastTime = 0;public MyEditText(Context context) {super(context);
}public MyEditText(Context context, AttributeSet attrs) {super(context, attrs);
}public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);
}@Overrideprotected void onSelectionChanged(int selStart, int selEnd) {super.onSelectionChanged(selStart, selEnd);//把光标位置固定在最末this.setSelection(this.getText().length());
}@Overridepublic boolean onTouchEvent(MotionEvent event) {//屏蔽双击事件switch (event.getAction()) {case MotionEvent.ACTION_DOWN:long currentTime = System.currentTimeMillis();if (currentTime - lastTime 500) {
lastTime = currentTime;return true;
} else {
lastTime = currentTime;
}break;
}return super.onTouchEvent(event);
}
}
如果需要完整的demo,可以访问我的github:
https://github.com/jb274585381/VerifyCodeViewDemo
结语
有时候我们实现一个需求,不光要考虑最终的效果,还要考虑时间成本,能用最简单的方法实现当然是最好的,省下的时间拿来打把昆特牌也是不错的。而且写的代码越少,出错的几率越低嘛,是不是~ 好了今天就分享到这里,我要去熬我的西米露了。如有错误,欢迎大家指正。
【无门槛免费领】
535G超强程序员编程
0基础从入门到精通自学视频教程!
万水千山总是情,点个 “ 在看” 行不行
更多推荐
所有评论(0)