Вопрос: Закройте / спрячьте мягкую клавиатуру Android


у меня есть EditTextи Buttonв моем макете.

После записи в поле редактирования и нажатия на Button, Я хочу скрыть виртуальную клавиатуру. Я предполагаю, что это простой кусок кода, но где я могу найти его пример?


3030


источник


Ответы:


Вы можете заставить Android скрыть виртуальную клавиатуру, используя InputMethodManager , вызывая hideSoftInputFromWindow, передавая в токене окна, содержащего ваше сфокусированное изображение.

// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Это заставит клавиатуру быть скрытой во всех ситуациях. В некоторых случаях вы захотите пройти InputMethodManager.HIDE_IMPLICIT_ONLYкак второй параметр, чтобы убедиться, что вы скрываете клавиатуру, когда пользователь явно не заставлял ее отображаться (удерживая нажатой клавишу меню).

Заметка: Если вы хотите сделать это в Котлине, используйте: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager


4139



Чтобы помочь прояснить это безумие, я хотел бы начать с извинения от имени всех пользователей Android за простое смешное обращение с Google к мягкой клавиатуре. Причина в том, что так много ответов, по-разному, по одному и тому же вопросу, потому что этот API, как и многие другие в Android, ужасно разработан. Я не могу придумать ни одного вежливого способа заявить об этом.

Я хочу скрыть клавиатуру. Я ожидаю, что Android предоставит следующее заявление: Keyboard.hide(), Конец. Большое спасибо. Но у Android есть проблемы. Вы должны использовать InputMethodManagerчтобы скрыть клавиатуру. Хорошо, отлично, это API Android на клавиатуре. НО! Вы должны иметь Contextчтобы получить доступ к IMM. Теперь у нас есть проблема. Я могу скрыть клавиатуру от статического или служебного класса, который не нужен или нужен для каких-либо Context, или И еще хуже, IMM требует, чтобы вы указали, что View(или еще хуже, что Window) вы хотите скрыть клавиатуру FROM.

Это то, что скрывает клавиатуру так сложно. Дорогой Google: Когда я ищу рецепт пирога, нет RecipeProviderна Земле, которая откажется предоставить мне рецепт, если я не отвечу сначала, что торт будет съеден И где он будет съеден !!

Эта печальная история заканчивается уродливой правдой: чтобы скрыть клавиатуру Android, вам потребуется предоставить две формы идентификации: Contextи либо Viewили Window,

Я создал статический метод утилиты, который может выполнять работу ОЧЕНЬ солидно, если вы вызываете это из Activity,

public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    //Find the currently focused view, so we can grab the correct window token from it.
    View view = activity.getCurrentFocus();
    //If no view currently has focus, create a new one, just so we can grab a window token from it
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Имейте в виду, что этот метод утилиты ТОЛЬКО работает при вызове из Activity! Вышеупомянутый метод вызывает getCurrentFocusцели Activityдля получения правильного токена окна.

Но предположим, что вы хотите скрыть клавиатуру от EditTextразмещенный в DialogFragment? Вы не можете использовать вышеописанный метод:

hideKeyboard(getActivity()); //won't work

Это не сработает, потому что вы передадите ссылку на Fragmentхозяин Activity, который не будет сфокусирован FragmentПоказано! Вау! Поэтому, скрывая клавиатуру от фрагментов, я прибегаю к более низкому уровню, более обыченному и уродливому:

public static void hideKeyboardFrom(Context context, View view) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Ниже приведена дополнительная информация, полученная из большего количества времени, потраченного впустую:

О windowSoftInputMode

Есть еще один спорный момент, о котором нужно знать. По умолчанию Android автоматически назначит начальный фокус на первый EditTextили настраиваемый контроль в вашем Activity, Из этого следует, что InputMethod (обычно мягкая клавиатура) будет реагировать на событие фокусировки, показывая себя. windowSoftInputModeатрибут в AndroidManifest.xml, когда установлено значение stateAlwaysHidden, инструктирует клавиатуру игнорировать этот автоматически назначенный начальный фокус.

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

Почти невероятно, похоже, что он ничего не делает для предотвращения открытия клавиатуры при касании элемента управления (если только focusable="false"и / или focusableInTouchMode="false"назначаются элементу управления). По-видимому, параметр windowSoftInputMode применяется только к событиям автоматической фокусировки, а не к фокусу событий, вызванных событиями касания.

Следовательно, stateAlwaysHiddenОЧЕНЬ плохо назван. Его, возможно, следует назвать ignoreInitialFocusвместо.

Надеюсь это поможет.


UPDATE: больше способов получить токен окна

Если нет сфокусированного представления (например, может случиться, если вы только что изменили фрагменты), есть другие представления, которые будут снабжать полезный токен окна.

Это альтернативы для вышеуказанного кода if (view == null) view = new View(activity);Они не относятся прямо к вашей деятельности.

Внутри класса фрагмента:

view = getView().getRootView().getWindowToken();

Учитывая фрагмент fragmentв качестве параметра:

view = fragment.getView().getRootView().getWindowToken();

Начиная с вашего контента:

view = findViewById(android.R.id.content).getRootView().getWindowToken();

ОБНОВЛЕНИЕ 2: очистить фокус, чтобы снова не показывать клавиатуру, если вы открываете приложение из фона

Добавьте эту строку в конец метода:

view.clearFocus();


919



Также полезно скрывать мягкую клавиатуру:

getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);

Это можно использовать для подавления мягкой клавиатуры до тех пор, пока пользователь не коснется редактирования editText.


734



I got one more solution to hide keyboard:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

Here pass HIDE_IMPLICIT_ONLY at the position of showFlag and 0 at the position of hiddenFlag. It will forcefully close soft Keyboard.


288



Meier's solution works for me too. In my case the top level of my App is a tabHost and I want to hide the keyword when switching tabs - I get the window token from the tabHost View.

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 0);
    }
}

124



Please try this below code in onCreate()

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);

111



Update: I don't know why this solution is not work any more ( I just tested on Android 23). Please use the solution of Saurabh Pareek instead. Here it is:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Hide:
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
//Show
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

Old answer:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

104



protected void hideSoftKeyboard(EditText input) {
    input.setInputType(0);
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}

61



If all the other answers here don't work for you as you would like them to, there's another way of manually controlling the keyboard.

Create a function with that will manage some of the EditText's properties:

public void setEditTextFocus(boolean isFocused) {
    searchEditText.setCursorVisible(isFocused);
    searchEditText.setFocusable(isFocused);
    searchEditText.setFocusableInTouchMode(isFocused);

    if (isFocused) {
        searchEditText.requestFocus();
    }
}

Then, make sure that onFocus of the EditText you open/close the keyboard:

searchEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (v == searchEditText) {
            if (hasFocus) {
                // Open keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
            } else {
                // Close keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
            }
        }
    }
});

Now, whenever you want to open the keyboard manually call:

setEditTextFocus(true);

And for closing call:

setEditTextFocus(false);

55



Saurabh Pareek has the best answer so far.

Might as well use the correct flags, though.

/* hide keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

/* show keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

Example of real use

/* click button */
public void onClick(View view) {      
  /* hide keyboard */
  ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
      .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

  /* start loader to check parameters ... */
}

/* loader finished */
public void onLoadFinished(Loader<Object> loader, Object data) {
    /* parameters not valid ... */

    /* show keyboard */
    ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
        .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

    /* parameters valid ... */
}

47



from so searching, here I found an answer that works for me

// Show soft-keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

// Hide soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

42