How to enable keyboard on touch after disabling it

2019-02-20 14:34发布

I am using a custom in-app keyboard, so I need to disable the system keyboard. I can do that with

editText.setShowSoftInputOnFocus(false);

for Android API 21+. But to do the same thing down to API 11, I am doing

editText.setTextIsSelectable(true);

Sometimes I want to show the system keyboard again after disabling it with setTextIsSelectable. But I can't figure out how. Doing the following does show the system keyboard, but if the user hides the keyboard and then clicks the EditText again, the keyboard still won't show.

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, 0);

I guess I could do editText.setOnFocusChangeListener and then manually show or hide the system keyboard, but I would prefer to undo whatever setTextIsSelectable did. The following also does not work:

editText.setFocusable(true);
editText.setFocusableInTouchMode(true);
editText.setClickable(true);
editText.setLongClickable(true);

How do I do it?

Related question

1条回答
来,给爷笑一个
2楼-- · 2019-02-20 14:44

Short answer

Doing the following will reverse the effects of setTextIsSelectable(true) and allow the keyboard to show again when the EditText receives focus.

editText.setTextIsSelectable(false);
editText.setFocusable(true);
editText.setFocusableInTouchMode(true);
editText.setClickable(true);
editText.setLongClickable(true);
editText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
editText.setText(editText.getText(), TextView.BufferType.SPANNABLE);

Explanation

The thing that prevents the keyboard from showing is isTextSelectable() being true. You can see that here (thanks to @adneal).

The source code for setTextIsSelectable is

public void setTextIsSelectable(boolean selectable) {
    if (!selectable && mEditor == null) return; // false is default value with no edit data

    createEditorIfNeeded();
    if (mEditor.mTextIsSelectable == selectable) return;

    mEditor.mTextIsSelectable = selectable;
    setFocusableInTouchMode(selectable);
    setFocusable(selectable);
    setClickable(selectable);
    setLongClickable(selectable);

    // mInputType should already be EditorInfo.TYPE_NULL and mInput should be null

    setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
    setText(mText, selectable ? BufferType.SPANNABLE : BufferType.NORMAL);

    // Called by setText above, but safer in case of future code changes
    mEditor.prepareCursorControllers();
}

Thus, the code in the short answer section above first sets mTextIsSelectable to false with setTextIsSelectable(false) and then undoes all of the other side effects one-by-one.

查看更多
登录 后发表回答