Закрыть / скрыть программную клавиатуру Android

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

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

130 ответов

Решение

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

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

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

Эта печальная история заканчивается ужасной правдой: чтобы скрыть клавиатуру Android, вам потребуется предоставить 2 формы идентификации: 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 вместо.

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


ОБНОВЛЕНИЕ: Больше способов получить жетон окна

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

Это альтернативы для приведенного выше кода 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();

Вы можете заставить 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 в качестве второго параметра, чтобы убедиться, что вы скрываете клавиатуру только тогда, когда пользователь явно не заставлял ее появляться (удерживая меню).

Примечание: если вы хотите сделать это в Kotlin, используйте: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

Котлин Синтаксис

// Check if no view has focus:
 val view = this.currentFocus
 view?.let { v ->
  val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager 
  imm?.let { it.hideSoftInputFromWindow(v.windowToken, 0) }
 }

Также полезно скрыть софт-клавиатуру:

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

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

У меня есть еще одно решение, чтобы скрыть клавиатуру:

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

Здесь проходят HIDE_IMPLICIT_ONLY в положении showFlag а также 0 в положении hiddenFlag, Это принудительно закроет мягкую клавиатуру.

Решение Майера работает и для меня. В моем случае верхний уровень моего приложения - это tabHost, и я хочу скрыть ключевое слово при переключении вкладок - я получаю маркер окна из представления tabHost.

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

Пожалуйста, попробуйте этот код ниже onCreate()

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

Обновление: я не знаю, почему это решение больше не работает (я только что протестировал на Android 23). Пожалуйста, используйте вместо этого решение Saurabh Pareek. Вот:

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

Старый ответ:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
protected void hideSoftKeyboard(EditText input) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}

Если все остальные ответы здесь не работают для вас, как вы хотели бы, есть другой способ ручного управления клавиатурой.

Создать функцию, которая будет управлять некоторыми из EditTextСвойства:

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

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

Затем убедитесь, что на фокусе EditText Вы открываете / закрываете клавиатуру:

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);
            }
        }
    }
});

Теперь, когда вы хотите открыть клавиатуру вручную, позвоните:

setEditTextFocus(true);

И для закрытия звонка:

setEditTextFocus(false);

Пока у Саураба Парика лучший ответ.

Можно использовать и правильные флаги.

/* 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);

Пример реального использования

/* 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 ... */
}

От такого поиска, здесь я нашел ответ, который работает для меня

// 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);

Краткий ответ

В вашем OnClick слушатель вызов onEditorAction из EditText с IME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
    }
});

Развертка

Я чувствую, что этот метод лучше, проще и более соответствует шаблону дизайна Android. В приведенном выше простом примере (и, как правило, в большинстве общих случаев) вы получите EditText у него был / был фокус, и он также обычно вызывал клавиатуру в первую очередь (он определенно способен вызывать ее во многих распространенных сценариях). Таким же образом, это должен быть тот, кто отпускает клавиатуру, обычно это может быть сделано ImeAction, Просто посмотри как EditText с android:imeOptions="actionDone" ведет себя, вы хотите добиться того же поведения теми же средствами.


Проверьте этот связанный ответ

Это должно работать:

public class KeyBoard {

    public static void show(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); // show
    }

    public static void hide(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); // hide
    }

    public static void toggle(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        if (imm.isActive()){
            hide(activity); 
        } else {
            show(activity); 
        }
    }
}

KeyBoard.toggle(activity);

Я использую пользовательскую клавиатуру для ввода шестнадцатеричного числа, поэтому я не могу показать клавиатуру IMM...

В v3.2.4_r1 setSoftInputShownOnFocus(boolean show) был добавлен, чтобы контролировать погоду или не отображать клавиатуру, когда TextView получает фокус, но он все еще скрыт, поэтому необходимо использовать отражение:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    try {
        Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
        method.invoke(mEditText, false);
    } catch (Exception e) {
        // Fallback to the second method
    }
}

Для более старых версий я получил очень хорошие результаты (но далеко не идеальные) с OnGlobalLayoutListener, добавленный с помощью ViewTreeObserver из моего корневого представления, а затем проверить, отображается ли клавиатура следующим образом:

@Override
public void onGlobalLayout() {
    Configuration config = getResources().getConfiguration();

    // Dont allow the default keyboard to show up
    if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
    }
}

Это последнее решение может показывать клавиатуру в течение доли секунды и портить ручки выбора.

Когда в клавиатуре вводится полный экран, onGlobalLayout не вызывается. Чтобы избежать этого, используйте TextView#setImeOptions(int) или в объявлении TextView XML:

android:imeOptions="actionNone|actionUnspecified|flagNoFullscreen|flagNoExtractUi"

Обновление: только что нашел, какие диалоги используют, чтобы никогда не показывать клавиатуру и работает во всех версиях:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

Слава Богу, его официально поддержали спустя 11 лет.

Сначала добавьте зависимость implementation 'androidx.core:core-ktx:1.6.0-beta01' приложение Gradle

      fun View.showKbd() {
    (this.context as? Activity)?.let {
        it.showKbd()
    }
}
fun View.hideKbd() {
    (this.context as? Activity)?.let {
        it.hideKbd()
    }
}

fun Fragment.showKbd() {
    activity?.let {
        it.showKbd()
    }
}
fun Fragment.hideKbd() {
    activity?.let {
        it.hideKbd()
    }
}

fun Context.showKbd() {
    (this as? Activity)?.let {
        it.showKbd()
    }
}
fun Context.hideKbd() {
    (this as? Activity)?.let {
        it.hideKbd()
    }
}

fun Activity.showKbd(){
    WindowInsetsControllerCompat(window, window.decorView).show(WindowInsetsCompat.Type.ime())
}
fun Activity.hideKbd(){
    WindowInsetsControllerCompat(window, window.decorView).hide(WindowInsetsCompat.Type.ime())
}
public void setKeyboardVisibility(boolean show) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(show){
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    }else{
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
    }
}

Теперь, почти 12 лет спустя, у нас наконец-то есть официальный, обратно совместимый способ сделать это с AndroidX Core 1.5+:

      fun View.hideKeyboard() = ViewCompat.getWindowInsetsController(this)
    ?.hide(WindowInsetsCompat.Type.ime())

или специально для фрагмента:

      fun Fragment.hideKeyboard() = ViewCompat.getWindowInsetsController(requireView())
    ?.hide(WindowInsetsCompat.Type.ime())

Я потратил более двух дней, работая над всеми решениями, опубликованными в ветке, и обнаружил, что их так или иначе не хватает. Мое точное требование - иметь кнопку, которая со 100% надежностью отображает или скрывает экранную клавиатуру. Когда клавиатура находится в скрытом состоянии, она не должна появляться снова, независимо от того, на каких полях ввода пользователь нажимает. Когда он находится в своем видимом состоянии, клавиатура не должна исчезать независимо от того, на какие кнопки нажимает пользователь. Это должно работать на Android 2.2+ вплоть до самых последних устройств.

Вы можете увидеть рабочую реализацию этого в моем приложении чистой RPN.

После тестирования многих из предложенных ответов на разных телефонах (включая устройства froyo и пряники) стало очевидно, что приложения для Android могут надежно:

  1. Временно скрыть клавиатуру. Он появится снова, когда пользователь выделит новое текстовое поле.
  2. Покажите клавиатуру, когда начинается действие, и установите флаг активности, указывающий, что клавиатура всегда должна быть видна. Этот флаг можно установить только при инициализации действия.
  3. Отметьте активность, чтобы никогда не показывать или не разрешать использование клавиатуры. Этот флаг можно установить только при инициализации действия.

Для меня временно скрыть клавиатуру недостаточно. На некоторых устройствах оно появится снова, как только будет выделено новое текстовое поле. Поскольку мое приложение использует несколько текстовых полей на одной странице, при фокусировке на новом текстовом поле скрытая клавиатура снова выскочит.

К сожалению, пункты 2 и 3 в списке работают только надёжно, когда работа начинается. После того, как действие стало видимым, вы не сможете постоянно скрывать или показывать клавиатуру. Хитрость заключается в том, чтобы фактически возобновить свою деятельность, когда пользователь нажимает кнопку переключения клавиатуры. В моем приложении, когда пользователь нажимает кнопку переключения клавиатуры, запускается следующий код:

private void toggleKeyboard(){

    if(keypadPager.getVisibility() == View.VISIBLE){
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, true);
        i.putExtras(state);

        startActivity(i);
    }
    else{
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, false);
        i.putExtras(state);

        startActivity(i);
    }
}

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

Внутри метода onCreate запускается следующий код:

if(bundle.getBoolean(SHOW_KEYBOARD)){
    ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(newEquationText,0);
    getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
else{
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
            WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}

Если должна отображаться программная клавиатура, то InputMethodManager должен показать клавиатуру, а в окне указывается, чтобы программный ввод был всегда видимым. Если программная клавиатура должна быть скрыта, то устанавливается WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM.

Этот подход надежно работает на всех устройствах, на которых я тестировал - от 4-летнего телефона HTC с Android 2.2 до Nexus 7 с 4.2.2. Единственный недостаток этого подхода - вы должны быть осторожны при обращении с кнопкой "назад". Поскольку мое приложение имеет только один экран (калькулятор), я могу переопределить onBackPressed() и вернуться на домашний экран устройства.

В качестве альтернативы этому универсальному решению, если вы хотите закрыть программную клавиатуру из любого места, не имея ссылки на поле (EditText), которое использовалось для открытия клавиатуры, но все же хотели сделать это, если поле было сфокусировано, вы можете использовать это (из Деятельности):

if (getCurrentFocus() != null) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

Благодаря этому такому ответу я получил следующее, что в моем случае прекрасно работает при прокрутке фрагментов ViewPager...

private void hideKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

private void showKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
    }
}

Приведенные выше ответы работают для разных сценариев, но если вы хотите спрятать клавиатуру внутри представления и изо всех сил пытаетесь получить правильный контекст, попробуйте следующее:

setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        hideSoftKeyBoardOnTabClicked(v);
    }
}

private void hideSoftKeyBoardOnTabClicked(View v) {
    if (v != null && context != null) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

и чтобы получить контекст, извлеките его из конструктора:)

public View/RelativeLayout/so and so (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
    init();
}

Если вы хотите закрыть программную клавиатуру во время модульного или функционального теста, вы можете сделать это, нажав кнопку "Назад" в вашем тесте:

// Close the soft keyboard from a Test
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);

Я поставил "кнопку назад" в кавычки, так как выше не вызывает onBackPressed() для рассматриваемой деятельности. Он просто закрывает клавиатуру.

Обязательно сделайте небольшую паузу, прежде чем двигаться дальше, поскольку для закрытия кнопки "назад" требуется некоторое время, поэтому последующие нажатия на "Виды" и т. Д. Не будут регистрироваться до тех пор, пока не произойдет короткая пауза (1 секунда достаточно длинная).

Вот как вы делаете это в Mono для Android (AKA MonoDroid)

InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
    imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);

Это сработало для меня из-за странного поведения клавиатуры

private boolean isKeyboardVisible() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    mRootView.getWindowVisibleDisplayFrame(r);

    int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
    return heightDiff > 100; // if more than 100 pixels, its probably a keyboard...
}

protected void showKeyboard() {
    if (isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if (getCurrentFocus() == null) {
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    } else {
        View view = getCurrentFocus();
        inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
    }
}

protected void hideKeyboard() {
    if (!isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View view = getCurrentFocus();
    if (view == null) {
        if (inputMethodManager.isAcceptingText())
            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
    } else {
        if (view instanceof EditText)
            ((EditText) view).setText(((EditText) view).getText().toString()); // reset edit text bug on some keyboards bug
        inputMethodManager.hideSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

â € ¢ Kotlin Version через Extension Function

Используя функции расширения kotlin, было бы так просто показать и скрыть программную клавиатуру.

ExtensionFunctions.kt

import android.app.Activity
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.fragment.app.Fragment

fun Activity.hideKeyboard(): Boolean {
    return (getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .hideSoftInputFromWindow((currentFocus ?: View(this)).windowToken, 0)
}

fun Fragment.hideKeyboard(): Boolean {
    return (context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .hideSoftInputFromWindow((activity?.currentFocus ?: View(context)).windowToken, 0)
}

fun EditText.hideKeyboard(): Boolean {
    return (context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .hideSoftInputFromWindow(windowToken, 0)
}

fun EditText.showKeyboard(): Boolean {
    return (context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .showSoftInput(this, 0)
}

â € ¢ Использование

Теперь в твоем Activity или Fragment, hideKeyboard() явно доступен, а также вызывает его из экземпляра EditText подобно:

editText.hideKeyboard()

Простой и легкий в использовании метод, просто вызовите hideKeyboardFrom(YourActivity.this); спрятать клавиатуру

/**
 * This method is used to hide keyboard
 * @param activity
 */
public static void hideKeyboardFrom(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

Просто используйте этот оптимизированный код в своей деятельности:

if (this.getCurrentFocus() != null) {
    InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

Добавьте к своей деятельности android:windowSoftInputMode="stateHidden" в файле манифеста. Пример:

<activity
            android:name=".ui.activity.MainActivity"
            android:label="@string/mainactivity"
            android:windowSoftInputMode="stateHidden"/>

У меня есть случай, когда мой EditText может быть расположен также в AlertDialogКлавиатура должна быть закрыта при отклонении. Следующий код, кажется, работает где угодно:

public static void hideKeyboard( Activity activity ) {
    InputMethodManager imm = (InputMethodManager)activity.getSystemService( Context.INPUT_METHOD_SERVICE );
    View f = activity.getCurrentFocus();
    if( null != f && null != f.getWindowToken() && EditText.class.isAssignableFrom( f.getClass() ) )
        imm.hideSoftInputFromWindow( f.getWindowToken(), 0 );
    else 
        activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN );
}

Работает как волшебное прикосновение каждый раз

private void closeKeyboard() {
    InputMethodManager inputManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

}

private void openKeyboard() {
    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    if(imm != null){
        imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
    }
}