Cerrar / ocultar el teclado virtual de Android


3820

Tengo una EditTexty una Buttonen 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 este es un código simple, pero ¿dónde puedo encontrar un ejemplo?

Al tocar fuera del teclado.


13
¿Qué sucede si solo tiene un EditText y varios botones, como casillas de verificación y radios? El único lugar donde necesita el teclado es en el único EditText. ¿Cómo se registra para saber que se eligió / hizo clic en otra cosa para ocultar el teclado?
AlikElzin-kilaka 01 de

14
me siento estupido. No puedo ocultar el teclado en ICS. Intenté todos los métodos aquí y combinaciones de ellos. De ninguna manera. El método para mostrarlo funciona, pero no puedo ocultarlo sin importar qué ficha de viento, ocultar banderas, configuraciones de manifiesto o velas para ningún santo. En el teclado siempre veo esto: I / LatinIME (396): InputType.TYPE_NULL se especifica W / LatinIME (396): Clase de entrada inesperada: inputType = 0x00000000 imeOptions = 0x00000000
rompe

44
/ ** * Este método se usa para ocultar el teclado virtual. * @param activity * / public void hideSoftKeyboard (Actividad de actividad) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); }
Harshal Benake

esto funcionó para mí
nmxprime

Con los dispositivos que aumentan el tamaño y la resolución de la pantalla, la ocultación del teclado virtual se vuelve menos importante.
Al-Kathiri Khalid el

Respuestas:


2038

Para ayudar a aclarar esta locura, me gustaría comenzar disculpándome en nombre de todos los usuarios de Android por el tratamiento absolutamente ridículo del teclado suave de Google. 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á terriblemente diseñada. No se me ocurre ninguna forma cortés de decirlo.

Quiero esconder el teclado Espero para proporcionar Android con la siguiente afirmación: Keyboard.hide(). El fin. Muchas gracias. Pero Android tiene un problema. Debe usar el InputMethodManagerpara ocultar el teclado. OK, bien, esta es la API de Android para el teclado. ¡PERO! Debes tener un Contextpara poder acceder 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 especifique de qué View(o peor aún, de qué Window) quiere ocultar el teclado.

Esto es lo que hace que ocultar el teclado sea tan desafiante. Estimado Google: ¡Cuando busco la receta de un pastel, no hay nadie RecipeProvideren la Tierra que se niegue a proporcionarme la receta a menos que responda primero a 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.

He creado un método de utilidad estática 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 getCurrentFocusal objetivo Activitypara obtener el token de ventana adecuado.

Pero supongamos que desea ocultar el teclado de un EditTexthost 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 Fragmenthost del sistema Activity, que no tendrá control enfocado mientras Fragmentse muestra! ¡Guauu! 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 hay información adicional obtenida de más tiempo perdido persiguiendo esta solución:

Acerca de windowSoftInputMode

Hay otro punto de contención a tener en cuenta. Por defecto, Android asignará automáticamente el foco inicial al primer EditTextcontrol enfocable en su Activity. Naturalmente, se deduce que InputMethod (generalmente el teclado virtual) responderá al evento de enfoque mostrándose. El windowSoftInputModeatributo en AndroidManifest.xml, cuando se establece en stateAlwaysHidden, indica al teclado que ignore este foco inicial asignado automáticamente.

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

Casi increíblemente, parece no hacer nada para evitar que el teclado se abra cuando se 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, stateAlwaysHiddenes MUY mal nombrado. Quizás debería llamarse en su ignoreInitialFocuslugar.

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


2
Muy buen artículo. Sin embargo, una cosa es que si inicia otra actividad que activa el teclado, este seguirá estando presente cuando regrese. Se solucionó eso quitando el teclado usando su método al salir de la actividad principal.
Oyvind

3
@rmirabelle FragmentParece que puedes usarlogetActivity().getWindow().getDecorView()
McX

1
Esta publicación es genial, pero te faltan dos partes muy importantes. Los sutiles cambios realizados por versión y por fabricación. Por ejemplo, en un Samsung galaxy s6 necesitamos usar .clearFocus () antes de ocultar el teclado ... si no, el teclado todavía aparecerá en el segundo clic del texto de edición: S
Warpzit

17
Google realmente debería proporcionar esa Keyboard.hide();utilidad
HendraWD

1
[someView] .getContext () << Puede ser el caso de la actividad. Es el mismo objeto siempre. (Excepto servicios internos ...)
Oliver Dixon

4419

Puede forzar 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á al teclado a ocultarse en todas las situaciones. En algunos casos, querrá pasar InputMethodManager.HIDE_IMPLICIT_ONLYcomo el segundo parámetro para asegurarse de que solo oculta 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

Sintaxis de Kotlin

// Check if no view has focus:
 val view = this.currentFocus
 view?.let { v ->
  val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager 
  imm?.hideSoftInputFromWindow(v.windowToken, 0)
 }

14
Gracias, esto parece funcionar muy bien si se usa 0 como segundo parámetro. Pero si uso InputMethodManager.HIDE_IMPLICIT_ONLY el teclado nunca está oculto (aunque no estoy presionando el menú). ¿Alguna pista?
RoflcoptrException

27
Frio. Solo para aclarar, esto solo lo descarta si está presente, pero no evitará que aparezca, ¿verdad?
Cheezmeister

15
Puede ser útil llamar a editText.clearFocus () antes de ocultar el softInput
user2224350

111
Llamando editText.clearFocus()a continuación, InputMethodManager.HIDE_IMPLICIT_ONLYfunciona incluso en4.1
sprocket12

11
Lo que funcionó para mí en 4.4 / htc se ejecutó View focused = getCurrentFocus()para obtener lo que definitivamente es la vista actualmente enfocada, la llamada focused.clearFocus()y luego inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0)(con marcas claras).
Ionoclast Brigham

806

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.


116
También puede lograr el mismo efecto agregando android: windowSoftInputMode = "stateHidden" en su actividad en el manifiesto.
BoD

77
Intenté esto en un Fragmento (haciendo referencia a la actividad propietaria) en API Nivel 9 y desafortunadamente no funcionó. Intenté llamarlo en onResume y onActivityCreated - sin efecto.
AgentKnopf

2
Estoy trabajando en un diálogo y esto funcionó. Estoy usando Android 3.2. Lo puse en el método onCreateDialog (Bundle). No funcionó en el método onCreate. Diálogo de diálogo = super.onCreateDialog (savedInstanceState); dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams. SOFT_INPUT_STATE_ALWAYS_HIDDEN); El resultado es que mi vista con EditTexts aparece sin el teclado. Cuando el usuario toca un texto de edición, aparece el teclado.
flobacca

44
Esto no funciona cuando el foco todavía está en EditText (como, después de tocar un botón). Use la solución de Reto para eso.
Noumenon

44
¿Por qué anular la configuración del manifiesto es una mala idea? Estoy llamando a esto desde un fragmento. No hay una configuración de manifiesto que se aplique a un fragmento ...
Greg Ennis

349

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í pasa HIDE_IMPLICIT_ONLYen la posición de showFlagy 0en la posición de hiddenFlag. Se cerrará con fuerza el teclado suave.


44
Estás utilizando una bandera de ocultar en el parámetro showflags. Esto solo funciona porque las constantes usan los mismos enteros. Ejemplo usando las banderas correctas
Alex

probado en Android 4.0, me gusta esta solución, porque tengo múltiples textos de edición, botones en esa actividad, que pueden tener foco

32
@ Mark: Debido a que el método se llama "toggleSoftInput", no "hideSoftInput" :)
Sver

19
Esta solución muestra el teclado si está oculto. No es correcto
Michael Katkov

1
@AkashAggarwal: "funciona" si ignoras el hecho de que solo funcionó para ti porque se estaba mostrando el teclado. (CAMBIA la visibilidad del teclado: se oculta cuando se muestra, ¡PERO lo muestra cuando está oculto!) ¿Puede GARANTIZAR que, en todas las circunstancias, en todos los dispositivos, para todas las versiones futuras de Android, el teclado NO será mostrando en el momento que llamas esto? Si es así, ¡adelante y úsalo!
ToolmakerSteve

149

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 de pestañas: obtengo el token de la ventana de la vista tabHost.

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

Tengo esto para trabajar con SearchView también. Vea a continuación mi respuesta. Gracias mckoss!
Azurespot

139

Por favor intente esto debajo del código en onCreate()

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

2
Este método funciona como una forma de evitar el error "no se puede ocultar el teclado virtual " en 2.0 y 2.1 como se describe en code.google.com/p/android/issues/detail?id=7115 ... el método hideSoftInputFromWindow enumerado anteriormente no funcionó cuando lo probé, pero editView.setInputType (0) sí.
Spike Williams el

18
Esto es legítimo por Javadoc (no es un truco), aunque reescribiría el método comoeditView.setInputType(InputType.TYPE_NULL);
Bostone

3
esto funciona, sin embargo, oculta el androide: pista. Estoy usando Android 1.5
Tirtha

Esto es ideal para cuando necesita cerrar el teclado desde un cuadro de diálogo, no necesita obtener una instancia ni nada y puede asignar esto a todos los textos de edición cuando el usuario presiona un botón que cierra el cuadro de diálogo
I'm_With_Stupid

Funciona, pero también está ocultando el cursor. Necesito el cursor, pero no el teclado del sistema.
Stefan Brendle

129

Actualización: no sé por qué esta solución ya no funciona (acabo de probar en Android 23). Utiliza 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);

Vieja respuesta:

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

8
¿Dónde debo colocar este código? He intentado pegar getWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); en onCreate () pero el teclado no está oculto
user2236096

no funciona, probado en radioGroup.setOnCheckedChangeListener, API 23
Christian Schäfer

Si mira más de cerca, InputMethodManager.HIDE_IMPLICIT_ONLY y InputMethodManager.SHOW_IMPLICIT tienen el mismo valor, que es "1", por lo que no hay diferencia entre estas llamadas. => no funciona
Palejandro

si llama a imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0); entonces el teclado se mostrará en la pantalla :) La mejor implementación es: github.com/ravindu1024/android-keyboardlistener Shame en Android SDK
Duna

I don't know why this solution is not work any more- porque es Android , todo podrá cambiar, tal vez en parte debido a un mal diseño ... Escribimos descuidadamente, luego tachamos todo y reescribimos todo.
Rey Rey

89
protected void hideSoftKeyboard(EditText input) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}

55
¡Esto funcionó para mí! Pero, ¿por qué pusiste input.setInputType (0) ? No podía interactuar con EditTextView cuando tenía esa línea de código (funcionó cuando la eliminé ).
ymerdrengene

Probablemente input.getContext().getSystemService(Context.INPUT_METHOD_SERVICE).
CoolMind

Lo eliminé input.setInputType(0);de este código. Cambió el comportamiento del teclado y inputTypepara el EditText.
CoolMind

74

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 al enfocar EditTextcuando abra / 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, llame manualmente:

setEditTextFocus(true);

Y para cerrar la llamada:

setEditTextFocus(false);

+1: si desea comenzar una actividad con el teclado cerrado, use esta solución y agregue un onclicklistener que establezca setEditTextFocus (verdadero). Funciona como el encanto!
schlingel

Obtuve 'No se puede resolver el contexto del símbolo', en la séptima y décima línea del segundo bloque de código.
gimmegimme

Utilice getContext () en su lugar
Rotemmiz

61

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

1
Este es el más eficiente para la última versión. Siempre será necesario ajustarlo para versiones anteriores. Especialmente antes de v3.
Alex

2
@Mazen: usofragment.getActivity().getSystemService();
Johan S

Esta es la respuesta más completa, que abarca tanto mostrar como ocultar.
André Staltz el

44
No. En mi Samsung Tab, Android 5.0, el llamado código de "ocultar teclado" de arriba CAMBIARÁ el teclado virtual; si ya está oculto, lo mostrará. Hay una razón por la que esta función tiene TOGGLE en el nombre.
ToolmakerSteve

57

de esa búsqueda, 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);

El único que funcionó para mí para un Motorola con Android 5.1
GMX

55

La respuesta corta

En su OnClickoyente llame al onEditorActionde la 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 anterior (y generalmente en la mayoría de los casos comunes) tendrá un EditTextfoco que tiene / tuvo y también fue el que invocó el teclado en primer lugar (definitivamente es capaz de invocarlo en muchos escenarios comunes). De la misma manera, que debe ser el que para liberar el teclado, por lo general lo que puede hacerse por una ImeAction. Solo vea cómo se comporta un EditTextcon android:imeOptions="actionDone", desea lograr el mismo comportamiento por los mismos medios.


Comprueba esta respuesta relacionada


Esta es la respuesta. Único método que funciona en versión cruzada. Volví a esta pregunta para publicar esta respuesta porque no creía que nadie más lo supiera
Noah Passalacqua

Esta debería ser la respuesta correcta. En lugar de engañar a Android para que oculte el teclado cuando realmente debería estar allí, le decimos que el usuario ha terminado, lo que a su vez activa la misma ImeAction [nombre estúpido, lo admito] como si el usuario hubiera hecho clic en "HECHO" en el teclado . De esta manera, no hay diferencia si el usuario confirma la entrada en el teclado o toca el botón UI.
Oliver Hausler

46

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

Funcionó en parte, incluso si se ocultó el teclado "isActive ()" devuelve falso!
xpto

Por supuesto que sí, se supone que debe hacerlo. O tal vez no te entiendo. De todos modos, se puede complementar con la clase hide()y show()métodos para tener más control sobre cuando debe mostrar y cuándo no. Funciona para mí, yo también lo hice :)
Editaré el

@YoushaAleayoub sí, lo hará. KeyBoard.toggle(fragment.getActivity())
slinden77

@ slinden77, lol, estoy hablando de tu respuesta ... no esta que has comentado. Entonces esa respuesta todavía NO funcionará.
Yousha Aleayoub

@YoushaAleayoub uhm sí, lo hará. La pregunta original no menciona fragmentos, usted es quien mencionó los fragmentos. Entonces mi respuesta es perfectamente válida. Para usarlo con fragmentos, llame al método de manera diferente a a Fragment, como un comentario. Aprenda a usar métodos, por favor, y luego regrese. Estás confundiendo a la gente con tus respuestas tontas
slinden77

43

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

En v3.2.4_r1 setSoftInputShownOnFocus(boolean show)se agregó para controlar el clima o no para mostrar el teclado cuando TextView obtiene el foco, pero todavía 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 a ViewTreeObserverdesde mi 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 se mete con 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 nunca mostrar el teclado y funciona en todas las versiones:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

Gracias. Las dos banderas FLAG_ALT_FOCUSABLE_IM y FLAG_ALT_FOCUSABLE_IM son realmente lo único que ayudó en mi caso. No quería que se mostrara un teclado en mi actividad, ni siquiera cuando el usuario hizo clic en editar texto. (Hice mi propio "teclado").
Daniel Novak

Solución genial, sin embargo, si su actividad frontal no es a pantalla completa, el teclado es visible detrás de él. También la ayuda para el movimiento del cursor del teclado también es visible. Y no es skinnable.
Halxinate el

Secundo que. De todas las formas posibles, solo funciona el método getWindow (). SetFlags (), al menos en Android 5.1. Tenga en cuenta que setSoftInputShownOnFocus () ahora está configurado como ShowSoftInputOnFocus () y ya no está oculto, pero no funciona, al menos no cuando el usuario toca el campo.
olefevre

Su "actualización" fue la única solución de trabajo para mí. Estoy buscando una solución al menos dos horas :)
Stefan Brendle

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

30

He pasado más de dos días trabajando en todas las soluciones publicadas en el hilo y he encontrado que carecen de una forma u otra. Mi requisito exacto es tener un botón que muestre u oculte con un 100% de confiabilidad el teclado en pantalla. Cuando el teclado está 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 últimos dispositivos.

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

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. Oculta temporalmente el teclado. Volverá a aparecer de nuevo 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 su teclado siempre debe estar visible. Este indicador solo se puede establecer cuando se inicia una actividad.
  3. Marque una actividad para nunca mostrar o permitir el uso del teclado. Este indicador solo se puede establecer cuando se inicia una actividad.

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

Lamentablemente, los elementos 2 y 3 de la lista solo funcionan con fiabilidad cuando se inicia una actividad. Una vez que la actividad se ha hecho visible, no puede ocultar o mostrar permanentemente el teclado. 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 de alternar 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 la actividad actual tenga su estado guardado 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 virtual, se le indica al InputMethodManager que muestre el teclado y se le indica a la ventana que haga siempre visible la entrada virtual. Si el teclado virtual debe estar oculto, se configura WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM.

Este enfoque funciona de manera confiable en todos los dispositivos 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 del dispositivo.


1
solución alternativa, pero creo que es demasiado, para recrear miles de objetos solo para ocultar el teclado. No sé quién diseñó el IMM para Android, pero huele a un APi de Windows. En mi opinión, un buen IME debería tener dos métodos: ocultar y mostrar :-)
rompe

Todo es cierto, pero mi solución tiene una ventaja: ¡siempre funciona! No hay otra solución que pueda encontrar que siempre cambie el teclado, independientemente de qué campos en la interfaz de usuario tengan el foco, qué ha hecho el usuario para alternar y teclado y qué versión de Android están ejecutando: - \
Luke Sleeman

Hombre, estoy totalmente desesperado por ocultar el teclado. Probé miles de cosas y nadie trabaja. Pero su solución es demasiado para mí, tendría que recrear como 10 fragmentos, inicializar servicios, eliminar muchas referencias débiles ... ¿sabes? el GC simplemente tiraría como 25mb: S ... Todavía
estoy

@Dmitry bueno, no es un mundo hola ... es una aplicación compleja para tabletas. Me niego a descargarlo por completo de la memoria solo para ocultar un teclado tonto ... De todos modos, encontré algo que funciona combinando las mil soluciones propuestas aquí :)
rompe el

27

Alternativamente a esta solución completa , si desea cerrar el teclado virtual desde cualquier lugar sin tener una referencia al campo (Editar Texto) que se utilizó para abrir el teclado, pero aún así quería hacerlo si el campo estaba enfocado, podría usar esto (de una Actividad):

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

25

Gracias a esta respuesta SO , deduje lo siguiente que, en mi caso, funciona muy bien al desplazarse 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);
    }
}

21

Las respuestas anteriores funcionan para diferentes escenarios, pero si desea ocultar el teclado dentro de una vista y lucha por 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 que el contexto lo obtenga del constructor :)

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

18

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 de retroceso" entre comillas, ya que lo anterior no activa onBackPressed()la actividad en cuestión. Simplemente cierra el teclado.

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


16

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

1
¿Qué hay searchboxen el fragmento?
PCoder

16

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

1
Creo que probé 10 respuestas antes de esta. Había perdido la esperanza. Gracias hombre.
Bolling

¿Qué es mRootView?
justdan0227

14

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

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

14

Método simple y fácil de usar, solo 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);
}

13

Simplemente use este código optimizado en su actividad:

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

Funciona bien. Gracias
Alif

12
public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

después de esa llamada en onTouchListener:

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

Intente esto también, esto funcionó para mí: InputMethodManager imm = ((InputMethodManager) getSystemService (Activity.INPUT_METHOD_SERVICE)); imm.hideSoftInputFromWindow (getWindow (). getCurrentFocus (). getWindowToken (), 0);
zmicer

12

utilizar este

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

12

Para mi caso, estaba usando un SearchView en la barra de acción. Después de que un usuario realiza una búsqueda, el teclado se abriría nuevamente.

El uso de InputMethodManager no cerró el teclado. Tuve que borrar el enfoque y establecer el foco de la vista de búsqueda en falso:

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

1
Muy inteligente. Si el usuario desea otra búsqueda, simplemente haga clic en buscar nuevamente.
Alex

SearchView no tiene un clearFocus()en las páginas de la API de Android, por lo que esto no funcionó para mí, pero otra solución sí (consulte mi respuesta a continuación).
Azurespot


12

Tengo el caso, donde mi 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 );
}

1
Esta solución es mejor porque no tiene que controlar qué EditText pasa como parámetro para ocultar el método hideSoftInputFromWindow (). ¡Funciona muy bien!
Billyjoker

12

Casi he probado todas estas respuestas, tuve algunos problemas al azar, especialmente con el Samsung Galaxy S5.

Lo que termino es forzar el espectáculo y esconderse, y funciona perfectamente:

/**
 * 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);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.