在点击EditText的时候它会获得焦点并弹出软键盘,EditText继承成自TextView,只要和点击事件有关的那么必定会走view的分发事件并分发到onTouchEvent,代码如下所示:
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (mEditor != null) {
mEditor.onTouchEvent(event);
if (mEditor.mSelectionModifierCursorController != null
&& mEditor.mSelectionModifierCursorController.isDragAcceleratorActive()) {
return true;
}
}
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 the long press should have triggered an
* insertion action mode, we can now actually show it.
*/
if (mEditor != null && mEditor.mDiscardNextActionUp && action == MotionEvent.ACTION_UP) {
mEditor.mDiscardNextActionUp = false;
if (mEditor.mIsInsertionActionModeStartPending) {
mEditor.startInsertionActionMode();
mEditor.mIsInsertionActionModeStartPending = 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, mSpannable, 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 = mSpannable.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 (isTextEditable() && mEditor.mShowSoftInputOnFocus && 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 (touchIsFinished && (isTextEditable() || textIsSelectable)) {
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
if (isTextEditable() && mEditor.mShowSoftInputOnFocus && 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;
}
}
其中 touchIsFinished = (action == MotionEvent.ACTION_UP) && (mEditor == null || !mEditor.mIgnoreActionUpEvent) && isFocused();是在手指抬起并且获得了焦点的情况下为true,那么让EditText不弹键盘的可控点就是
isTextEditable() || textIsSelectable
这两个参数,其中isEnable代表当前控件是否可用,如果不想弹系统默认键盘,而想弹自定义键盘显然这个属性不能用。
boolean isTextEditable() {
return mText instanceof Editable && onCheckIsTextEditor() && isEnabled();
}
public boolean onCheckIsTextEditor() {
return mEditor != null && mEditor.mInputType != EditorInfo.TYPE_NULL;
}
而onCheckIsTextEditor方法中有mEditor.mInputType != EditorInfo.TYPE_NULL,那么不弹键盘的话可以设置curEditText.setInputType(InputType.TYPE_NULL),而mText instanceof Editable是否属于Editable,要看你设置的text是否是SpannableStringBuilder类型的,如果不是或者下面的方法为true也可以
public boolean isTextSelectable() {
return mEditor == null ? false : mEditor.mTextIsSelectable;
}
因为是或者所以setTextIsSelectable(false)不可以控制键盘不弹出,如果不满足这些条件,还有一个mEditor.mShowSoftInputOnFocus属性,如下
if (isTextEditable() && mEditor.mShowSoftInputOnFocus && imm != null) {
imm.showSoftInput(this, 0);
}
可以通过方法setShowSoftInputOnFocus(false)设置键盘不弹出,综上所述想让键盘不弹出来可以设置
setShowSoftInputOnFocus(false) Added in API level 21
setInputType(InputType.TYPE_NULL) Added in API level 3
最后注意一下兼容性,其中你如果想要EditText没有焦点的话用setInputType(InputType.TYPE_NULL),需要焦点的话用setShowSoftInputOnFocus(false)