Tengo un EditTexty un Buttonen mi diseño.

Después de escribir en el campo de edición y hacer clic en Button, quiero ocultar el teclado virtual al tocar fuera del teclado. Supongo que este es un código simple, pero ¿dónde puedo encontrar un ejemplo?

respuesta

Puede obligar a Android a ocultar el teclado virtual usando InputMethodManager , llamando hideSoftInputFromWindowy pasando el token de la ventana que contiene su vista enfocada.

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

Esto obligará a ocultar el teclado en todas las situaciones. En algunos casos, querrá pasarlo InputMethodManager.HIDE_IMPLICIT_ONLYcomo el segundo parámetro para asegurarse de que solo oculta el teclado cuando el usuario no lo obligó explícitamente a aparecer (manteniendo presionado el menú).

Nota: si quieres hacer esto en Kotlin, usa: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

Sintaxis de Kotlin

// Only runs if there is a view that is currently focused
this.currentFocus?.let { view ->
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
    imm?.hideSoftInputFromWindow(view.windowToken, 0)
}

Para ayudar a aclarar esta locura, me gustaría comenzar pidiendo disculpas en nombre de todos los usuarios de Android por el tratamiento francamente ridículo de Google del teclado virtual. La razón por la que hay tantas respuestas, cada una diferente, para la misma pregunta simple es que esta API, como muchas otras en Android, está horriblemente diseñada. No se me ocurre ninguna forma educada de decirlo.

Quiero ocultar el teclado. Espero proporcionar a Android la siguiente declaración: Keyboard.hide(). El fin. Muchísimas gracias. Pero Android tiene un problema. Debe utilizar InputMethodManagerpara ocultar el teclado. OK, bien, esta es la API de Android para el teclado. ¡PERO! Se requiere que tenga un Contextpara obtener acceso al IMM. Ahora tenemos un problema. Es posible que desee ocultar el teclado de una clase estática o de utilidad que no tiene uso ni necesidad de ningún archivo Context. o Y MUCHO peor, el IMM requiere que especifique de qué View(o peor aún, de qué Window) desea ocultar el teclado.

Esto es lo que hace que esconder el teclado sea tan desafiante. Estimado Google: Cuando estoy buscando la receta de un pastel, no hay nadie RecipeProvideren la Tierra que se niegue a proporcionarme la receta a menos que primero responda QUIÉN se comerá el pastel Y dónde se comerá.

Esta triste historia termina con la fea verdad: para ocultar el teclado de Android, deberá proporcionar 2 formas de identificación: a Contexty a Viewo a Window.

Creé un método de utilidad estática que puede hacer el trabajo MUY sólidamente, siempre que lo llame desde un archivo 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);
}

Tenga en cuenta que este método de utilidad SÓLO funciona cuando se llama desde un Activity! El método anterior llama getCurrentFocusal objetivo Activitypara obtener el token de ventana adecuado.

Pero suponga que desea ocultar el teclado de un EditTextservidor alojado en un DialogFragment? No puedes usar el método anterior para eso:

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

¡Esto no funcionará porque pasará una referencia al Fragmenthost Activityde , que no tendrá ningún control enfocado mientras Fragmentse muestre! ¡Guau! Entonces, para ocultar el teclado de los fragmentos, recurro al nivel inferior, más común y más feo:

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

A continuación se muestra información adicional obtenida de más tiempo perdido persiguiendo esta solución:

Acerca de windowSoftInputMode

Hay otro punto de discordia a tener en cuenta. De forma predeterminada, Android asignará automáticamente el enfoque inicial al primer EditTextcontrol o control enfocable en su archivo Activity. Naturalmente, se deduce que InputMethod (típicamente el teclado en pantalla) responderá al evento de enfoque mostrándose a sí mismo. El windowSoftInputModeatributo en AndroidManifest.xml, cuando se establece en stateAlwaysHidden, indica al teclado que ignore este enfoque inicial asignado automáticamente.

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

Casi increíblemente, parece que no hace nada para evitar que el teclado se abra cuando toca el control (a menos que focusable="false"y/o focusableInTouchMode="false"estén asignados al control). Aparentemente, la configuración de windowSoftInputMode se aplica solo a los eventos de enfoque automático, no a los eventos de enfoque activados por eventos táctiles.

Por lo tanto, stateAlwaysHiddenestá MUY mal nombrado. Tal vez debería llamarse ignoreInitialFocusen su lugar.


ACTUALIZACIÓN: más formas de obtener un token de ventana

Si no hay una vista enfocada (por ejemplo, puede suceder si solo cambió fragmentos), hay otras vistas que proporcionarán un token de ventana útil.

Estas son alternativas para el código anterior. if (view == null) view = new View(activity); No se refieren explícitamente a su actividad.

Dentro de una clase de fragmento:

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

Dado un fragmento fragmentcomo parámetro:

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

A partir de su cuerpo de contenido:

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

ACTUALIZACIÓN 2: Desactive el enfoque para evitar mostrar el teclado nuevamente si abre la aplicación desde el fondo

Agregue esta línea al final del método:

view.clearFocus();

También es útil para ocultar el teclado virtual:

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

Esto se puede usar para suprimir el teclado virtual hasta que el usuario toque la Vista de edición de texto.

Tengo una solución más para ocultar el teclado:

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

Aquí pase HIDE_IMPLICIT_ONLYen la posición de showFlagy 0en la posición de hiddenFlag. Cerrará con fuerza el teclado suave.

La solución de Meier también funciona para mí. En mi caso, el nivel superior de mi aplicación es un host de pestañas y quiero ocultar la palabra clave al cambiar de pestaña; obtengo el token de ventana de la Vista del host de pestañas.

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

Por favor, intente este código a continuación en onCreate()

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

Actualización: no sé por qué esta solución ya no funciona (acabo de probar en Android 23). Utilice la solución de Saurabh Pareek en su lugar. Aquí está:

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

Respuesta antigua:

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

Si todas las otras respuestas aquí no funcionan para usted como le gustaría, hay otra forma de controlar manualmente el teclado.

Cree una función con la que administrará algunas de las EditTextpropiedades de:

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

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

Luego, asegúrese de que onFocus EditTextabra/cierre el teclado:

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

Ahora, cada vez que desee abrir el teclado manualmente, llame a:

setEditTextFocus(true);

Y para la llamada de cierre:

setEditTextFocus(false);

Saurabh Pareek tiene la mejor respuesta hasta ahora.

Sin embargo, también podría usar las banderas correctas.

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

Ejemplo de uso real

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

de tanto buscar, aquí encontré una respuesta que me funciona

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

la respuesta corta

En tu OnClickoyente llama al onEditorActiondel EditTextconIME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

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

el desglose

Siento que este método es mejor, más simple y más alineado con el patrón de diseño de Android. En el ejemplo simple de arriba (y generalmente en la mayoría de los casos comunes) tendrá un EditTextque tiene/tuvo foco y también fue el que invocó el teclado en primer lugar (definitivamente es capaz de invocarlo en muchos escenarios comunes). De igual manera, debe ser quien libere el teclado, normalmente eso lo puede hacer un ImeAction. Solo vea cómo se comporta un EditTextcon android:imeOptions="actionDone", desea lograr el mismo comportamiento por los mismos medios.


Verifique esta respuesta relacionada

Esto debería funcionar:

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

Estoy usando un teclado personalizado para ingresar un número hexadecimal, por lo que no puedo mostrar el teclado IMM ...

En v3.2.4_r1 setSoftInputShownOnFocus(boolean show)se agregó para controlar el clima o no mostrar el teclado cuando se enfoca un TextView, pero aún está oculto, por lo que se debe usar la reflexión:

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

Para versiones anteriores, obtuve muy buenos resultados (pero lejos de ser perfectos) con un OnGlobalLayoutListener, agregado con la ayuda de ViewTreeObservermi vista raíz y luego comprobando si el teclado se muestra así:

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

Esta última solución puede mostrar el teclado por una fracción de segundo y alterar los controladores de selección.

Cuando en el teclado ingresa a pantalla completa, onGlobalLayout no se llama. Para evitar eso, use TextView#setImeOptions(int) o en la declaración XML de TextView:

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

Actualización: acabo de encontrar qué diálogos usan para no mostrar nunca el teclado y funciona en todas las versiones:

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

Pasé más de dos días trabajando en todas las soluciones publicadas en el hilo y encontré que faltaban de una forma u otra. Mi requisito exacto es tener un botón que con un 100% de confiabilidad muestre u oculte el teclado en pantalla. Cuando el teclado está en su estado oculto, no debería volver a aparecer, sin importar en qué campos de entrada haga clic el usuario. Cuando está en su estado visible, el teclado no debe desaparecer sin importar en qué botones haga clic el usuario. Esto debe funcionar en Android 2.2+ hasta los dispositivos más recientes.

Puede ver una implementación funcional de esto en mi aplicación limpia RPN .

Después de probar muchas de las respuestas sugeridas en varios teléfonos diferentes (incluidos los dispositivos froyo y gingerbread), se hizo evidente que las aplicaciones de Android pueden:

  1. Ocultar temporalmente el teclado. Volverá a aparecer cuando un usuario enfoque un nuevo campo de texto.
  2. Muestre el teclado cuando comience una actividad y establezca una bandera en la actividad que indique que el teclado siempre debe estar visible. Este indicador solo se puede establecer cuando una actividad se está inicializando.
  3. Marque una actividad para que nunca se muestre o permita el uso del teclado. Este indicador solo se puede establecer cuando una actividad se está inicializando.

Para mí, ocultar temporalmente el teclado no es suficiente. En algunos dispositivos volverá a aparecer tan pronto como se enfoca un nuevo campo de texto. Como mi aplicación usa varios campos de texto en una página, al enfocar un nuevo campo de texto, el teclado oculto volverá a aparecer.

Desafortunadamente, los elementos 2 y 3 de la lista solo funcionan de manera confiable cuando se inicia una actividad. Una vez que la actividad se vuelve visible, no puede ocultar ni mostrar el teclado de forma permanente. El truco consiste en reiniciar su actividad cuando el usuario presiona el botón de alternancia del teclado. En mi aplicación, cuando el usuario presiona el botón del teclado, se ejecuta el siguiente código:

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

Esto hace que el estado de la actividad actual se guarde en un paquete, y luego se inicia la actividad, pasando por un valor booleano que indica si el teclado debe mostrarse u ocultarse.

Dentro del método onCreate se ejecuta el siguiente código:

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

Si se debe mostrar el teclado en pantalla, se le indica a InputMethodManager que muestre el teclado y se le indica a la ventana que haga que la entrada en pantalla esté siempre visible. Si el teclado en pantalla debe ocultarse, se establece WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM.

Este enfoque funciona de forma fiable en todos los dispositivos en los que he probado, desde un teléfono HTC de 4 años con Android 2.2 hasta un Nexus 7 con 4.2.2. La única desventaja con este enfoque es que debe tener cuidado al manejar el botón Atrás. Como mi aplicación esencialmente solo tiene una pantalla (es una calculadora), puedo anular onBackPressed() y volver a la pantalla de inicio de los dispositivos.

Como alternativa a esta solución integral , si desea cerrar el teclado en pantalla desde cualquier lugar sin tener una referencia al campo (EditText) que se usó para abrir el teclado, pero aún desea hacerlo si el campo está enfocado, puede usar esto (de una actividad):

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

Gracias a Dios es compatible oficialmente después de 11 años.

Primero agregue la dependencia implementation 'androidx.core:core-ktx:1.7.0'a la aplicación gradle

Aquí está el proyecto simple en github

import android.app.Activity
import android.content.Context
import android.view.View
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity


fun View.showKeyboard() = (this.context as? Activity)?.showKeyboard()
fun View.hideKeyboard() = (this.context as? Activity)?.hideKeyboard()

fun Fragment.showKeyboard() = activity?.let(FragmentActivity::showKeyboard)
fun Fragment.hideKeyboard() = activity?.hideKeyboard()

fun Context.showKeyboard() = (this as? Activity)?.showKeyboard()
fun Context.hideKeyboard() = (this as? Activity)?.hideKeyboard()

fun Activity.showKeyboard() = WindowInsetsControllerCompat(window, window.decorView).show(WindowInsetsCompat.Type.ime())
fun Activity.hideKeyboard() = WindowInsetsControllerCompat(window, window.decorView).hide(WindowInsetsCompat.Type.ime())

Gracias a esta respuesta SO , derivé lo siguiente que, en mi caso, funciona bien al desplazarme por los fragmentos de un 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);
    }
}

Las respuestas anteriores funcionan para diferentes escenarios, pero si desea ocultar el teclado dentro de una vista y tiene dificultades para obtener el contexto correcto, intente esto:

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

y para obtener el contexto, obténgalo del constructor :)

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

Si desea cerrar el teclado virtual durante una unidad o prueba funcional, puede hacerlo haciendo clic en el "botón Atrás" de su prueba:

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

Pongo "botón atrás" entre comillas, ya que lo anterior no activa onBackPressed()la actividad en cuestión. Solo cierra el teclado.

Asegúrese de hacer una breve pausa antes de continuar, ya que se tarda un poco en cerrar el botón Atrás, por lo que los clics posteriores en Vistas, etc., no se registrarán hasta después de una breve pausa (1 segundo es tiempo suficiente ).

Ahora, casi 12 años después, finalmente tenemos una forma oficial compatible con versiones anteriores de hacer esto con AndroidX Core 1.5+ :

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

o específicamente para Fragmento:

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

Así es como lo haces en Mono para Android (también conocido como MonoDroid)

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

Esto funcionó para mí por todo el extraño comportamiento del teclado.

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

Método simple y fácil de usar, simplemente llame a hideKeyboardFrom(YourActivity.this); para ocultar el teclado

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

Solo usa este código optimizado en tu actividad:

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

Agregue a su actividad android:windowSoftInputMode="stateHidden"en el archivo Manifiesto. Ejemplo:

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

Kotlin VersionvíaExtension Function

Con las funciones de extensión de Kotlin, sería muy sencillo mostrar y ocultar el teclado en pantalla.

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

• Uso

Ahora en su Activityo Fragment, hideKeyboard()es claramente accesible, así como llamarlo desde una instancia EditTextcomo:

editText.hideKeyboard()

Para teclado abierto:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edtView, InputMethodManager.SHOW_IMPLICIT);

Para cerrar/ocultar teclado:

 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
 imm.hideSoftInputFromWindow(edtView.getWindowToken(), 0);

Tengo el caso, donde my EditTextpuede ubicarse también en un AlertDialog, por lo que el teclado debe cerrarse al descartar. El siguiente código parece estar funcionando en cualquier lugar:

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