最近在看EditText的源码,有人问到如果不使用系统的软键盘,在网上看了下资料,发现对于这个问题的解决都比较的浅薄,没有深入到源码层面。
都是通过设置activity中软键盘设置,或者是设置EditText的inputType这些属性,但是都是只能实现部分功能,而且会影响本来EditText的光标已经插入等等功能。
在看过源码以后对软键盘特别留意了下,发现软键盘的弹出只是通过一个boolean值来进行控制。
看弹出软键盘的源码:
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;
}
这是TextView的onTouch中的一段代码(因为EditText继承自TextView,但是基本没有实现什么方法,所有的功能TextView以及实现)
通过上变的代码我们可以发现,是否显示软件盘是通过
textIsSelectable 以及 mEditor.mShowSoftInputOnFocus来进行控制的,但是
textIsSelectable修改以后会影响插入光标的功能,所以只能修改mEditor.mShowSoftInputOnFocus
而修改这个就很简单了,通过凡是就可以做到:
下边是反射的代码:(亲测有效,只屏蔽了软键盘)
/**
* 设置EditTextView不显示软键盘
* @param editText
*/
public static void setEditTextViewNoSoftInput(EditText editText){
Class cls = editText.getClass().getSuperclass();
LogUtils.e("edit", "==========="+ cls.getSuperclass());
Class textCls = cls.getSuperclass();
try {
Field field = textCls.getDeclaredField("mEditor");
LogUtils.e("edit", "field==" + field.getName());
field.setAccessible(true);
Object editObj = field.get(editText);
Class cls_edit = editObj.getClass();
Field focus_field = cls_edit.getDeclaredField("mShowSoftInputOnFocus");
focus_field.setAccessible(true);
Object focus_obj = focus_field.get(editObj);
LogUtils.e("edit",focus_obj + "");
focus_field.set(editObj,false);
} catch (NoSuchFieldException e) {
LogUtils.e("edit", "===========" + e.getMessage());
e.printStackTrace();
} catch (IllegalAccessException e) {
LogUtils.e("edit", "===========" + e.getMessage());
e.printStackTrace();
}
}