Pregunta Cerrar / ocultar el teclado suave de Android


Yo tengo un EditText y un Button en mi diseño.

Después de escribir en el campo de edición y hacer clic en Button, Quiero ocultar el teclado virtual. Supongo que se trata de una simple pieza de código, pero ¿dónde puedo encontrar un ejemplo?


3085


origen


Respuestas:


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 suave. La razón por la que hay tantas respuestas, cada una diferente, para la misma pregunta simple es porque esta API, como muchas otras en Android, está horriblemente diseñada. No puedo pensar en una forma educada de decirlo.

Quiero esconder el teclado Espero proporcionar a Android la siguiente declaración: Keyboard.hide(). El fin. Muchas gracias. Pero Android tiene un problema. Debes usar el InputMethodManager para esconder el teclado OK, bien, esta es la API de Android para el teclado. ¡PERO! Se requiere que tengas un Context para tener 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 o necesidad de ninguna Context. o Y mucho peor, el IMM requiere que especifiques qué View (o peor, qué Window) desea ocultar el teclado DE.

Esto es lo que hace que esconder el teclado sea tan desafiante. Querido Google: Cuando estoy buscando la receta de un pastel, no hay RecipeProvider en la Tierra que se negaría a proporcionarme la receta, a menos que primero responda QUIÉN se comerá el pastel Y dónde se lo 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: Context y ya sea un View o una Window.

Creé un método de utilidad estático que puede hacer el trabajo MUY sólidamente, siempre que lo llames 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 SÓLO funciona cuando se lo llama desde un Activity! El método anterior llama getCurrentFocus del objetivo Activity para buscar el token de ventana apropiado

Pero supongamos que quiere ocultar el teclado de una EditText alojado en un DialogFragment? No puede usar el método anterior para eso:

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

Esto no funcionará porque pasarás una referencia al Fragmentel anfitrión Activity, que no tendrá control enfocado mientras Fragment ¡se muestra! ¡Guauu! Entonces, para esconder 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 encuentra información adicional obtenida de más tiempo perdido persiguiendo esta solución:

Acerca de WindowSoftInputMode

Todavía hay otro punto de discordia que debe tenerse en cuenta. De forma predeterminada, Android asignará automáticamente el foco inicial al primer EditText o control enfocable en su Activity. Naturalmente, se deduce que InputMethod (por lo general, el teclado virtual) responderá al evento de enfoque mostrándose a sí mismo. los windowSoftInputMode atributo en AndroidManifest.xml, cuando se establece en stateAlwaysHidden, instruye al teclado para 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 windowSoftInputMode se aplica solo a los eventos de enfoque automático, no a los eventos de enfoque activados desde eventos táctiles.

Por lo tanto, stateAlwaysHidden es MUY mal llamado de hecho. Quizás debería ser llamado ignoreInitialFocus en lugar.

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 los 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 un parámetro:

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

A partir de tu cuerpo de contenido:

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

ACTUALIZACIÓN 2: enfoque claro 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();


1008



Puede obligar a Android a ocultar el teclado virtual con el InputMethodManagerllamando 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á al teclado a ocultarse en todas las situaciones. En algunos casos, querrás pasar InputMethodManager.HIDE_IMPLICIT_ONLY como el segundo parámetro para garantizar que solo ocultas el teclado cuando el usuario no lo forzó explícitamente a aparecer (manteniendo presionado el menú).

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


4171



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 realmente la vista editText.


741



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í paso HIDE_IMPLICIT_ONLY en el puesto de showFlag y 0 en el puesto de hiddenFlag. Cerrará con fuerza el teclado suave.


294



La solución de Meier también funciona para mí. En mi caso, el nivel superior de mi aplicación es un tabHost y quiero ocultar la palabra clave cuando cambio las pestañas: obtengo el token de la ventana de la vista de pestaña de acceso.

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

128



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

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

115



Actualizar: No sé por qué esta solución ya no funciona (acabo de probar en Android 23). Por favor use la solución de Saurabh Pareek en 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 anterior:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

107