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

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

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

30 ответов


чтобы помочь прояснить это безумие, я хотел бы начать с извинений от имени всех пользователей 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, который не будет иметь сфокусированного контроля, пока есть! Вау! Итак, для сокрытия клавиатуры от фрагментов я прибегаю к нижнему уровню, более распространенному и уродливому:

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


вы можете заставить 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


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

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, и я хочу скрыть ключевое слово при переключении вкладок - я получаю токен окна из представления 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). Пожалуйста, используйте решение Саурабх 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) {
    input.setInputType(0);
    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);

Саурабх Pareek имеет лучший ответ до сих пор.

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

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

в В3.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);

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

Если должна быть показана мягкая клавиатура, то InputMethodManager должен показать клавиатуру, а окну - сделать мягкий ввод всегда видимым. Если софт клавиатура должна быть скрыта, а затем WindowManager.LayoutParams.Установлен ФЛАГ_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 секунда достаточно долго 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"/>

использовать

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

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

использование InputMethodManager не закрывало клавиатуру. Я должен был clearFocus и установить focusable вида поиска в false:

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

я почти пробовал все эти ответы, у меня были некоторые случайные проблемы, особенно с 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);
        }
    }
}

простой и легкий в использовании способ, просто позвонить hideKeyboardFrom(YourActivity.это); спрятать клавиатуру

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

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