Вопрос

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

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

Это было полезно?

Решение

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

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

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

Эта печальная история заканчивается уродливой правдой:чтобы скрыть клавиатуру Android, вам потребуется предоставить 2 формы идентификации:a Context и либо View или a 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.Из этого естественным образом следует, что метод ввода (обычно программная клавиатура) отреагирует на событие фокусировки, показав себя.В windowSoftInputMode атрибут в AndroidManifest.xml, когда установлено значение stateAlwaysHidden, предписывает клавиатуре игнорировать этот автоматически назначенный начальный фокус.

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

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

Следовательно, stateAlwaysHidden действительно, ОЧЕНЬ неудачно назван.Возможно, это следует назвать ignoreInitialFocus вместо этого.

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


Обновить:Другие способы получить токен window

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

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

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

Синтаксис Kotlin

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

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

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

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

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

Решение Мейера работает и для меня тоже.В моем случае верхний уровень моего приложения - это TabHost, и я хочу скрыть ключевое слово при переключении вкладок - я получаю токен window из представления 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).Пожалуйста, используйте решение Саурабх Парик вместо этого.Вот оно:

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 это имеет / имело фокус, и это также обычно было тем, кто вызывал клавиатуру в первую очередь (она определенно способна вызывать ее во многих распространенных сценариях).Таким же образом, IT должен быть тем, кто освобождает клавиатуру, обычно это может быть сделано с помощью 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 не вызывается.Чтобы избежать этого, используйте Текстовый просмотр#setImeOptions(int) или в XML-объявлении TextView:

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

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

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
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);
    }
}

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

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

После тестирования многих предложенных ответов на нескольких разных телефонах (включая устройства froyo и gingerbread) стало очевидно, что приложения для 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);
    }
}

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

Внутри метода 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);
}

Если должна быть показана программная клавиатура, то InputMethod Manager получает указание показать клавиатуру, а окну - сделать программный ввод всегда видимым.Если программная клавиатура должна быть скрыта, то WindowManager.LayoutParams.Установлен ФЛАГ_ALT_FOCUSABLE_IM.

Этот подход надежно работает на всех устройствах, на которых я тестировал - от телефона HTC 4-летней давности под управлением 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 секунда - это достаточно долго для ime).

Вот как вы делаете это в Mono для Android (ОН ЖЕ 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);
    }
}

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

<activity
            android:name=".ui.activity.MainActivity"
            android:label="@string/mainactivity"
            android:windowSoftInputMode="stateHidden"/>
public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

после этого вызовите OnTouchListener:

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

используй это

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

В моем случае я использовал SearchView на панели действий.После того, как пользователь выполнит поиск, клавиатура снова откроется.

Использование InputMethod Manager не привело к закрытию клавиатуры.Мне пришлось очистить фокус и установить для фокусируемого вида поиска значение false:

mSearchView.clearFocus();
mSearchView.setFocusable(false);

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

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

У меня есть случай, когда мой 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 );
}

Я почти перепробовал все эти ответы, у меня возникли некоторые случайные проблемы, особенно с samsung galaxy s5.

В итоге я получаю принудительное отображение и скрытие, и это работает отлично:

/**
 * Force show softKeyboard.
 */
public static void forceShow(@NonNull Context context) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

/**
 * Force hide softKeyboard.
 */
public static void forceHide(@NonNull Activity activity, @NonNull EditText editText) {
    if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) {
        editText.requestFocus();
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

В некоторых случаях этот метод может сработать лучше всех остальных.Это спасает мой день :)

public static void hideSoftKeyboard(Activity activity) {
    if (activity != null) {
        InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (activity.getCurrentFocus() != null && inputManager != null) {
            inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
            inputManager.hideSoftInputFromInputMethod(activity.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

public static void hideSoftKeyboard(View view) {
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputManager != null) {
            inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top