这几天需要弄一个短信验证码输入框,输入框是一个继承自EditText的ClearableEditText,输入时候用的键盘是自定义的一个键盘,也就是说点击EditText的时候不能弹出系统键盘.
如果按正常逻辑 我们会在代码中直接设置EditText的InputType为InputType.TYPE_NULL 即
mSmsCodeInputEditText.setInputType(InputType.TYPE_NULL);
这时候我们发现EditText上那个一闪一闪的光标没了.这样的显示效果不够友好.
解决方法:
在xml布局文件中
android:inputType="none"
代码中设置:
mSmsCodeInputEditText.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int inType = mSmsCodeInputEditText.getInputType();
mSmsCodeInputEditText.setInputType(InputType.TYPE_NULL);
mSmsCodeInputEditText.onTouchEvent(event);
mSmsCodeInputEditText.setInputType(inType);
CharSequence text = mSmsCodeInputEditText.getText();
if (text instanceof Spannable) {
Spannable spanText = (Spannable) text;
Selection.setSelection(spanText, text.length());
}
return true;
}
});
即可完美解决问题.在点击的时候执行onTouchEvent之前将其InputType设置位null这时候键盘不会弹出来了,执行完onTouchEvent(弹键盘的操作就是在onTouchEvent)中,我们可以查看TextView的源码
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (mEditor != null) mEditor.onTouchEvent(event);
final boolean superResult = super.onTouchEvent(event);
/*
* Don't handle the release after a long press, because it will
* move the selection away from whatever the menu action was
* trying to affect.
*/
if (mEditor != null && mEditor.mDiscardNextActionUp && action == MotionEvent.ACTION_UP) {
mEditor.mDiscardNextActionUp = false;
return superResult;
}
final boolean touchIsFinished = (action == MotionEvent.ACTION_UP) &&
(mEditor == null || !mEditor.mIgnoreActionUpEvent) && isFocused();
if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
&& mText instanceof Spannable && mLayout != null) {
boolean handled = false;
if (mMovement != null) {
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
final boolean textIsSelectable = isTextSelectable();
if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && textIsSelectable) {
// The LinkMovementMethod which should handle taps on links has not been installed
// on non editable text that support text selection.
// We reproduce its behavior here to open links for these.
ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),
getSelectionEnd(), ClickableSpan.class);
if (links.length > 0) {
links[0].onClick(this);
handled = true;
}
}
if (touchIsFinished && (isTextEditable() || textIsSelectable)) {
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
if (!textIsSelectable && mEditor.mShowSoftInputOnFocus) {
handled |= imm != null && imm.showSoftInput(this, 0);
}
// The above condition ensures that the mEditor is not null
mEditor.onTouchUpEvent(event);
handled = true;
}
if (handled) {
return true;
}
}
return superResult;
}
看上面倒数第二个if,弹键盘的操作就在这个if判断语句里 imm.showSoftInput(this, 0);
再看isTextEditable()的实现:
boolean isTextEditable() {
return mText instanceof Editable && onCheckIsTextEditor() && isEnabled();
}
@Override
public boolean onCheckIsTextEditor() {
return mEditor != null && mEditor.mInputType != EditorInfo.TYPE_NULL;
}
可以看到如果mInputType是TYPE_NULL(0x00000000),条件不成立,键盘不弹起来.
当执行完onTouchEvent之后再将EditText的InputType设置为原先的类型.
注意: 在xml布局文件中设置EditText的inputType为none(android:inputType="none"),它的实际值和TYPE_NULL是不一样的. 所以不要将在xml文件中设置android:inputType="none" 的效果等同于在代码中设置text.setInputType(InputType.TYPE_NULL); 这两个设置完之后EditText的getInputType得到的值是不一样的.
android:inputType="none" getInputType的值对应 0x00020001
text.setInputType(InputType.TYPE_NULL); 对应0x00000000