Saltar al contenido

¿Cómo se cierra / oculta el teclado virtual de Android usando Java?

Esta inquietud se puede abordar de variadas maneras, pero en este caso te compartimos la que en nuestra opinión es la respuesta más completa.

Solución:

Puede forzar a Android a ocultar el teclado virtual usando InputMethodManager, llamando hideSoftInputFromWindow, 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 que el teclado se oculte en todas las situaciones. En algunos casos, querrá pasar InputMethodManager.HIDE_IMPLICIT_ONLY como segundo parámetro para garantizar que solo oculte el teclado cuando el usuario no lo obligó explícitamente a aparecer (manteniendo presionado el menú).

Nota: Si desea hacer esto en Kotlin, use:
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 disculpándome en nombre de todos los usuarios de Android por el tratamiento francamente ridículo de Google del teclado en pantalla. 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 una forma cortés 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. Debes usar el InputMethodManager para ocultar el teclado. Está bien, esta es la API de Android para el teclado. ¡PERO! Debes tener un Context para tener acceso al IMM. Ahora tenemos un problema. Es posible que desee ocultar el teclado a un static o clase de utilidad que no tiene uso o necesidad de ningún Context. o Y MUCHO peor, el IMM requiere que especifique qué View (o peor aún, qué Window) desea ocultar el teclado DE.

Esto es lo que hace que esconder el teclado sea tan difícil. Estimado Google: Cuando busco la receta de un pastel, no hay RecipeProvider en la Tierra que se negaría a darme la receta a menos que primero responda por 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, se le pedirá que proporcione 2 formas de identificación: a Context y ya sea un View o un Window.

He creado un static método de utilidad que puede hacer el trabajo MUY sólidamente, siempre que lo llame desde un 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 SOLO funciona cuando se llama desde un Activity! El método anterior llama getCurrentFocus del objetivo Activity para buscar el token de ventana adecuado.

Pero suponga que desea ocultar el teclado a un EditText alojado en un DialogFragment? No puede usar el método anterior para eso:

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

Esto no funcionará porque pasará una referencia al Fragmentanfitrión Activity, que no tendrá control enfocado mientras el Fragment ¡se muestra! ¡Guau! Entonces, para ocultar el teclado de los fragmentos, recurro al nivel más bajo, 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 que hay que tener en cuenta. De forma predeterminada, Android asignará automáticamente el enfoque inicial a la primera EditText o control enfocable en su Activity. Naturalmente, se deduce que InputMethod (normalmente el teclado virtual) responderá al evento de enfoque mostrándose a sí mismo. El windowSoftInputMode attribute en AndroidManifest.xml, cuando se establece en stateAlwaysHidden, indica al teclado que ignore este enfoque inicial asignado automáticamente.


Casi increíblemente, parece no hacer 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 windowSoftInputMode se aplica solo a eventos de enfoque automático, no a eventos de enfoque activados por eventos táctiles.

Por lo tanto, stateAlwaysHidden está MUY mal nombrado de hecho. Quizás debería llamarse ignoreInitialFocus en lugar de.

Espero que esto ayude.


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

Si no hay una vista enfocada (por ejemplo, puede suceder si acaba de cambiar 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); Estos no se refieren explícitamente a su actividad.

Dentro de una clase de fragmento:

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

Dado un fragmento fragment como 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: enfoque claro para evitar volver a mostrar el teclado 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 realmente toque la vista editText.

Comentarios y puntuaciones del tutorial

Ten en cuenta dar visibilidad a este enunciado si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *