Necesito hacer algo muy simple: averiguar si se muestra el teclado del software. ¿Es esto posible en Android?
516
Necesito hacer algo muy simple: averiguar si se muestra el teclado del software. ¿Es esto posible en Android?
Respuestas:
NUEVA RESPUESTA agregada el 25 de enero de 2012
Desde que escribí la respuesta a continuación, alguien me dio a conocer la existencia de ViewTreeObserver y sus amigos, API que han estado al acecho en el SDK desde la versión 1.
En lugar de requerir un tipo de diseño personalizado, una solución mucho más simple es dar a la vista raíz de su actividad un ID conocido, por ejemplo
@+id/activityRoot
, enganchar un GlobalLayoutListener en el ViewTreeObserver, y desde allí calcular la diferencia de tamaño entre la raíz de la vista de la actividad y el tamaño de la ventana:Usando una utilidad como:
¡Fácil!
Nota: Su aplicación debe establecer este indicador en el Manifiesto de Android; de lo
android:windowSoftInputMode="adjustResize"
contrario, la solución anterior no funcionará.RESPUESTA ORIGINAL
Sí, es posible, pero es mucho más difícil de lo que debería ser.
Si necesito preocuparme cuando el teclado aparece y desaparece (lo cual es bastante frecuente), entonces lo que hago es personalizar mi clase de diseño de nivel superior en una que anule
onMeasure()
. La lógica básica es que si el diseño se encuentra llenando significativamente menos que el área total de la ventana, entonces probablemente se muestre un teclado virtual.Luego, en tu clase de actividad ...
fuente
((ViewGroup) findViewById(android.R.id.content)).getChildAt(0)
android.R.id.content
), podrá decir con mayor confianza que, enSystem
lugar de su aplicación, la entidad está cambiando su altura. Sería mucho más seguro para el equipo de Android darnos un descanso y hacernos saber al menos cosas básicas sobre la entrada de SoftKeyboard.heightDiff
siempre incluirá la altura de la barra de acción. En la nueva respuesta que se ha ignorado al probar si esa altura es mayor que alguna constante, pero 100 píxeles no son suficientes para dispositivos xxhdpi como el Nexus 4. Considere convertir ese valor a DP si realmente desea utilizar este trabajo extravagante. alrededor.Espero que esto ayude a alguien.
La nueva respuesta que dio Reuben Scratton es excelente y realmente eficiente, pero realmente solo funciona si configura su windowSoftInputMode para ajustarResize. Si lo configura para ajustarPan, aún no es posible detectar si el teclado es visible o no con su fragmento de código. Para evitar esto, hice esta pequeña modificación al código anterior.
fuente
TwoDScrollerView
similar a stackoverflow.com/a/5224088/530513 aunque también con el zoom. El niño no era unImageView
diseño simple sino personalizado (se extiendeRelativeLayout
) pero no pudo detectar el teclado usando la solución recomendada a pesar de la configuraciónandroid:windowSoftInputMode="adjustResize"
. ¡Gracias!ActionBar
yActionBarSherlock
. ¡Muchas gracias! Por cierto, hay un métodor.height()
:)heightDiff > root.getRootView().getHeight() / 4
Es un buen valor para trabajar con dispositivos de alta resolución. 100 px es muy corto. en Nexus 5 con resolución de 1080x1920, 1920 - (996-75)>? 100 = 999 1920 - (1776-75)>? 100 = 219 // el teclado está funcionando en galaxy s2 con 480x800 res, 800 - (800-38)>? 100 = 38 800 - (410-38)>? 100 = 428 // el teclado está arriba, así que el número mágico 100px no es lo suficientemente bueno.Ha sido una eternidad en términos de computadora, ¡pero esta pregunta sigue siendo increíblemente relevante!
Así que he tomado las respuestas anteriores y las he combinado y refinado un poco ...
Funciona para mi :)
NOTA: Si nota que DefaultKeyboardDP no se ajusta a su dispositivo, juegue con el valor y publique un comentario para que todos sepan cuál debería ser el valor ... ¡finalmente obtendremos el valor correcto para todos los dispositivos!
Para más detalles, consulte la implementación en Cyborg
fuente
Perdón por la respuesta tardía, pero había creado una pequeña clase auxiliar para manejar eventos abiertos / cerrados con notificaciones a los oyentes y otras cosas útiles, puede ser que alguien lo encuentre útil:
Ejemplo de uso:
fuente
getLastKeyboardHeightInPx()
no incluye la altura de esa fila. ¿Conoces una manera de tenerlo en cuenta también?Algunas mejoras para evitar detectar erróneamente la visibilidad del teclado virtual en dispositivos de alta densidad:
El umbral de diferencia de altura debe definirse como 128 dp , no 128 píxeles .
Consulte el documento de diseño de Google sobre Metrics and Grid , 48 dp es de tamaño cómodo para objetos táctiles y 32 dp es mínimo para botones. El teclado virtual genérico debe incluir 4 filas de botones de tecla, por lo que la altura mínima del teclado debe ser: 32 dp * 4 = 128 dp , lo que significa que el tamaño del umbral debe transferirse a píxeles multiplicando la densidad del dispositivo. Para dispositivos xxxhdpi (densidad 4), el umbral de altura del teclado virtual debe ser 128 * 4 = 512 píxeles.
Diferencia de altura entre la vista raíz y su área visible:
altura de la vista raíz - altura de la barra de estado - altura del marco visible = parte inferior de la vista raíz - parte inferior del marco visible, ya que la altura de la barra de estado es igual a la parte superior del marco visible de la vista raíz.
fuente
Utilicé un poco de tiempo para resolver esto ... Ejecuté algunas CastExceptions, pero descubrí que puedes reemplazar LinearLayout en layout.xml con el nombre de la clase.
Me gusta esto:
De esa manera no te encontrarás con ningún problema de lanzamiento.
... y si no quieres hacer esto en cada página, te recomiendo que uses "MasterPage en Android". Vea el enlace aquí: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx
fuente
Comprobar la altura de los elementos no es confiable porque algunos teclados como WifiKeyboard tienen una altura cero.
En su lugar, puede usar el resultado de devolución de llamada de showSoftInput () y hideSoftInput () para verificar el estado del teclado. Detalles completos y código de ejemplo en
https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android
fuente
La idea es que, si necesita ocultar su teclado y verificar el estado de entrada suave al mismo tiempo, use la siguiente solución:
Este método devuelve verdadero si el teclado se mostró antes de ocultarse.
fuente
Descubrí que una combinación del método de @ Reuben_Scratton junto con el método de @ Yogesh parece funcionar mejor. Combinar sus métodos produciría algo como esto:
fuente
Puede observar la ocultación del teclado virtual mediante el uso de decorView de la actividad.
fuente
En lugar de asumir la diferencia de codificación, hice algo como esto, ya que no tenía opciones de menú en mi aplicación.
fuente
También hay una solución con inserciones del sistema, pero solo funciona con
API >= 21
(Android L
). Digamos que tieneBottomNavigationView
, que es hijo deLinearLayout
y necesita ocultarlo cuando se muestra el teclado:Todo lo que necesita hacer es extender
LinearLayout
de tal manera:La idea es que cuando se muestra el teclado, las inserciones del sistema se cambian con un
.bottom
valor bastante grande .fuente
Hay un método oculto que puede ayudar para esto
InputMethodManager.getInputMethodWindowVisibleHeight
,. Pero no sé por qué está oculto.fuente
Ninguna de estas soluciones funcionará para Lollipop tal como está. En Lollipop
activityRootView.getRootView().getHeight()
incluye la altura de la barra de botones, mientras que medir la vista no. He adaptado la mejor / más simple solución anterior para trabajar con Lollipop.fuente
Acabo de encontrar un error al usar la mayoría de las soluciones anteriores que sugieren agregar un número fijo.
S4 tiene una alta resolución, lo que resultó en que la altura de la barra de navegación sea de 100 px, por lo que mi aplicación piensa que el teclado está abierto todo el tiempo.
Por lo tanto, con el lanzamiento de todos los nuevos teléfonos de alta resolución, creo que usar un valor codificado no es una buena idea a largo plazo.
Un mejor enfoque que encontré después de algunas pruebas en varias pantallas y dispositivos fue utilizar el porcentaje. Obtenga la diferencia entre decorView y el contenido de su aplicación y luego verifique cuál es el porcentaje de esa diferencia. Según las estadísticas que obtuve, la mayoría de la barra de navegación (independientemente del tamaño, la resolución, etc.) ocupará entre el 3% y el 5% de la pantalla. Donde, como si el teclado estuviera abierto, ocupaba entre 47% y 55% de la pantalla.
Como conclusión, mi solución fue verificar si la diferencia es más del 10%, entonces supongo que es un teclado abierto.
fuente
Utilicé una ligera variante de la respuesta de Reuban, que resultó ser más útil en ciertas circunstancias, especialmente con dispositivos de alta resolución.
fuente
R.id.activityRoot
, simplemente puede usarandroid.R.id.content
cuál es exactamente lo que necesita.Ha sido para siempre en términos de la computadora, ¡pero esta pregunta sigue siendo increíblemente relevante! Así que he tomado las respuestas anteriores y las he combinado y refinado un poco ...
Esto funciona para mi.
fuente
Prueba esto:
fuente
Mi respuesta es básicamente la misma que la respuesta de Kachi, pero la envolví en una buena clase auxiliar para limpiar la forma en que se usa en mi aplicación.
Puede usar esto para detectar cambios en el teclado en cualquier lugar de la aplicación como este:
Nota: solo use una de las llamadas de "registro". Todos funcionan igual y solo están ahí por conveniencia
fuente
puedes probar esto, funciona muy bien para mí:
fuente
Estaba teniendo dificultades para mantener el estado del teclado al cambiar la orientación de los fragmentos dentro de un visor. No estoy seguro de por qué, pero parece ser inestable y actúa de manera diferente a una Actividad estándar.
Para mantener el estado del teclado en este caso, primero debe agregar
android:windowSoftInputMode = "stateUnchanged"
a suAndroidManifest.xml
. Sin embargo, puede notar que esto en realidad no resuelve todo el problema: el teclado no se abrió para mí si se abrió antes del cambio de orientación. En todos los demás casos, el comportamiento parecía ser correcto.Entonces, necesitamos implementar una de las soluciones mencionadas aquí. El más limpio que encontré fue el de George Maisuradze: use la devolución de llamada booleana de hideSoftInputFromWindow:
Almacené este valor en el
onSaveInstanceState
método de mi Fragmento y lo recuperéonCreate
. Luego, mostré por la fuerza el tecladoonCreateView
si tenía un valor detrue
(devuelve verdadero si el teclado es visible antes de ocultarlo realmente antes de la destrucción del Fragmento).fuente
Aquí está mi solución, y funciona. En lugar de buscar el tamaño de píxel, simplemente verifique que la altura de la vista de contenido haya cambiado o no:
fuente
No hagas ningún código duro. La mejor manera es que tiene que cambiar el tamaño de sus vistas mientras se enfoca en EditText con KeyBord Show. Puede hacer esto agregando la propiedad de cambio de tamaño de la actividad en el archivo de Manifiesto usando el siguiente código.
android:windowSoftInputMode="adjustResize"
fuente
Hay un método directo para descubrir esto. Y no requiere ningún cambio de diseño.
Por lo tanto, también funciona en modo inmersivo a pantalla completa.
El truco es que intentas ocultar o mostrar el teclado virtual y capturar el resultado de ese intento.
Sin pánico, esto realmente no muestra u oculta el teclado. Solo pedimos el estado.
Para mantenerse actualizado, simplemente puede repetir la operación, por ejemplo, cada 200 milisegundos, utilizando un controlador.
Encuentra una implementación aquí: https://stackoverflow.com/a/27567074/2525452
fuente
Creo que este método te ayudará a descubrir si keybord es visible o no.
fuente
La nueva respuesta de Reuben Scratton (calcular la diferencia de altura
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
) no funcionará en la actividad si configura el modo de barra de estado translúcido.Si usa la barra de estado translúcida,
activityRootView.getHeight()
nunca cambiará el clima si el teclado virtual está visible. siempre devolverá la altura de la actividad y la barra de estado.Por ejemplo, Nexus 4, Android 5.0.1, configurado
android:windowTranslucentStatus
en verdadero, devolverá 1184 para siempre, incluso si el iMe ha abierto. Si lo estableceandroid:windowTranslucentStatus
en falso, devolverá la Altura correctamente, si estoy invisible, devolverá 1134 (no incluye la barra de estado) 。Cierre la imagen, tal vez devolverá 5xx (depende de la altura de la imagen)No sé si el clima es un error, lo he probado en 4.4.4 y 5.0.1, el resultado es el mismo.
Entonces, hasta ahora, la segunda respuesta más acordada, la solución de Kachi será la forma más segura de calmar la altura del tiempo. Aquí hay una copia:
fuente
Un método que no necesita un LayoutListener
En mi caso, me gustaría guardar el estado del teclado antes de reemplazar mi Fragmento. Llamo al método hideSoftInputFromWindow from
onSaveInstanceState
, que cierra el teclado y me devuelve si el teclado estaba visible o no.Este método es sencillo pero puede cambiar el estado de su teclado.
fuente
Sé que esta es una publicación antigua, pero creo que este es el enfoque más simple que conozco y mi dispositivo de prueba es Nexus 5. No lo he probado en otros dispositivos. Espero que otros compartan su enfoque si encuentran que mi código no es bueno :)
imm.hideSoftInputFromWindow devuelve boolean.
Gracias,
fuente
La función anterior es la que uso para verificar si un teclado está visible. Si es así, entonces lo cierro.
A continuación se muestran los dos métodos requeridos.
Primero, defina la altura de la ventana viable en onCreate.
Luego, agregue un método booleano que obtenga la altura de la ventana en esa instancia. Si no coincide con el original (suponiendo que no lo esté cambiando en el camino ...), entonces, el teclado está abierto.
Frotz!
fuente
Sé cuán exacto puede determinar si el teclado está oculto o no.
Esto funciona para tabletas. Cuando la barra de navegación se muestra horizontalmente.
fuente