Ok, todos saben que para ocultar un teclado debes implementar:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
Pero el gran problema aquí es cómo ocultar el teclado cuando el usuario toca o selecciona cualquier otro lugar que no sea un EditText
softKeyboard.
Traté de usar el onTouchEvent()
en mi padre Activity
pero eso solo funciona si el usuario toca fuera de cualquier otra vista y no hay una vista de desplazamiento.
Traté de implementar un oyente de toque, clic y enfoque sin ningún éxito.
Incluso intenté implementar mi propia vista de desplazamiento para interceptar eventos táctiles, pero solo puedo obtener las coordenadas del evento y no hacer clic en la vista.
¿Hay una forma estándar de hacer esto? en iPhone fue realmente fácil.
android
android-softkeyboard
htafoya
fuente
fuente
getFields()
aquí: stackoverflow.com/questions/7790487/…Respuestas:
El siguiente fragmento simplemente oculta el teclado:
Puede poner esto en una clase de utilidad, o si lo está definiendo dentro de una actividad, evite el parámetro de actividad o llame
hideSoftKeyboard(this)
.La parte más complicada es cuándo llamarlo. Puede escribir un método que recorra cada
View
una de las actividades de su actividad y verifique si es uninstanceof EditText
registrosetOnTouchListener
de ese componente y todo estará en su lugar. En caso de que se pregunte cómo hacerlo, de hecho es bastante simple. Esto es lo que haces, escribes un método recursivo como el siguiente, de hecho, puedes usar esto para hacer cualquier cosa, como configurar tipos de letra personalizados, etc. Aquí está el métodoEso es todo, simplemente llame a este método después
setContentView
de su actividad. En caso de que se pregunte qué parámetro pasaría, es elid
del contenedor principal. Asigne unid
a su contenedor principal como<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>
y llama
setupUI(findViewById(R.id.parent))
, eso es todo.Si desea utilizar de manera eficaz, es posible crear una extendida
Activity
y poner este método en, y hacer todas las otras actividades en su aplicación se extienden esta actividad y llamar a susetupUI()
en elonCreate()
método.Espero eso ayude.
Si usa más de 1 actividad, defina la identificación común para el diseño primario como
<RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>
Luego extienda una clase desde
Activity
y definasetupUI(findViewById(R.id.main_parent))
Dentro de ellaOnResume()
y extienda esta clase en lugar de `` Actividadin your program
Aquí hay una versión de Kotlin de la función anterior:
fuente
if(activity.getCurrentFocus() != null) {...}
OnTouchListener
para ellos. Simplemente podría establecer esa lógica en unaViewGroup.onInterceptTouchEvent(MotionEvent)
vista raíz.Puede lograr esto siguiendo los siguientes pasos:
Haga que la vista principal (vista de contenido de su actividad) sea clicable y enfocable agregando los siguientes atributos
Implemente un método hideKeyboard ()
Por último, configure onFocusChangeListener de su texto de edición.
Como se señala en uno de los comentarios a continuación, esto podría no funcionar si la vista principal es una Vista de desplazamiento. Para tal caso, se puede agregar el ClickIn y focusableInTouchMode en la vista directamente debajo de ScrollView.
fuente
clickable
yfocusableInTouchMode
a miScrollView
elemento raíz . Tuve que agregar al padre directo de miEditText
que era unLinearLayout
.Simplemente anule el siguiente código en Actividad
fuente
La respuesta aceptada me parece un poco complicada.
Aquí está mi solución. Agregue una
OnTouchListener
a su diseño principal, es decir:y pon el siguiente código en el método onTouch.
De esta manera, no tiene que iterar sobre todas las vistas.
fuente
android:onClick="stealFocusFromEditTexts"
al xml de la vista principal y luegopublic void stealFocusFromEditTexts(View view) {}
a su actividad. El método de clic no necesita hacer nada, solo tiene que existir para que la vista principal sea enfocable / seleccionable, lo cual es necesario para robar el enfoque del niño EditTextTengo una solución más para ocultar el teclado:
Aquí pasa
HIDE_IMPLICIT_ONLY
en la posición deshowFlag
y0
en la posición dehiddenFlag
. Se cerrará con fuerza el teclado blando.fuente
Bueno, logré resolver el problema de alguna manera, anulé el dispatchTouchEvent en mi actividad, allí estoy usando lo siguiente para ocultar el teclado.
EDITAR: El método getFields () es solo un método que devuelve una matriz con los campos de texto en la vista. Para evitar crear esta matriz en cada toque, creé una matriz estática llamada sFields, que se devuelve en el método getFields (). Esta matriz se inicializa en los métodos onStart () como:
sFields = new EditText[] {mUserField, mPasswordField};
No es perfecto, el tiempo del evento de arrastre solo se basa en la heurística, por lo que a veces no se oculta al realizar clics largos, y también terminé creando un método para obtener todos los editTexts por vista; de lo contrario, el teclado se escondería y mostraría al hacer clic en otro EditText.
Aún así, soluciones más limpias y cortas son bienvenidas
fuente
getFields()
método? No tiene que ser exacto, solo un ejemplo con quizás solo algunos comentarios que indican que devuelve una matriz deEditText
objetos.Use OnFocusChangeListener .
Por ejemplo:
Actualización : también puede anular
onTouchEvent()
su actividad y verificar las coordenadas del toque. Si las coordenadas están fuera de EditText, oculte el teclado.fuente
Implementé dispatchTouchEvent en Activity para hacer esto:
y lo probé, funciona perfecto!
fuente
Una forma más de Kotlin y diseño de materiales usando TextInputEditText (este enfoque también es compatible con EditTextView ) ...
1.Haga clic y enfoque en la vista principal (vista de contenido de su actividad / fragmento) agregando los siguientes atributos
2.Cree una extensión para toda la Vista (por ejemplo, dentro de un archivo ViewExtension.kt):
3.Cree un BaseTextInputEditText que herede de TextInputEditText. Implemente el método onFocusChanged para ocultar el teclado cuando la vista no está enfocada:
4. Simplemente llame a su nueva vista personalizada en su XML:
Eso es todo. No es necesario modificar sus controladores (fragmento o actividad) para manejar este caso repetitivo.
fuente
Anular el envío público booleanoTouchEvent (evento MotionEvent) en cualquier actividad (o ampliar la clase de actividad)
Y eso es todo lo que necesitas hacer
fuente
Modifiqué la solución de Andre Luis IM. Logré esta:
Creé un método de utilidad para ocultar el teclado virtual de la misma manera que lo hizo Andre Luiz IM:
Pero en lugar de registrar un OnTouchListener para cada vista, que da un bajo rendimiento, registré el OnTouchListener solo para la vista raíz. Dado que el evento burbujea hasta que se consume (EditText es una de las vistas que lo consume por defecto), si llega a la vista raíz, es porque no se consumió, así que cierro el teclado virtual.
fuente
Soy consciente de que este hilo es bastante antiguo, la respuesta correcta parece válida y hay muchas soluciones de trabajo, pero creo que el enfoque que se indica a continuación podría tener un beneficio adicional con respecto a la eficiencia y la elegancia.
Necesito este comportamiento para todas mis actividades, por lo que creé una clase CustomActivity heredada de la clase Activity y "enganché" la función dispatchTouchEvent . Hay principalmente dos condiciones para cuidar:
Este es mi resultado:
Nota al margen: Además, asigno estos atributos a la vista raíz, lo que permite borrar el foco en cada campo de entrada y evitar que los campos de entrada se centren en el inicio de la actividad (haciendo que la vista de contenido sea el "foco de captura"):
fuente
Me gustó el enfoque de llamadas
dispatchTouchEvent
realizado por htafoya, pero:Entonces, hice esta solución algo más fácil:
Hay una desventaja:
Cambiar de uno
EditText
a otroEditText
hace que el teclado se oculte y vuelva a mostrar; en mi caso, se desea de esa manera, porque muestra que cambiaste entre dos componentes de entrada.fuente
Súplica: Reconozco que no tengo influencia, pero por favor toma en serio mi respuesta.
Problema: descarte el teclado virtual cuando haga clic fuera del teclado o edite texto con un código mínimo.
Solución: Biblioteca externa conocida como Butterknife.
Solución de una línea:
Solución más legible:
Explicación: enlace OnClick Listener a la ID principal del diseño XML de la actividad, de modo que cualquier clic en el diseño (no en el texto o teclado de edición) ejecutará ese fragmento de código que ocultará el teclado.
Ejemplo: si su archivo de diseño es R.layout.my_layout y su identificación de diseño es R.id.my_layout_id, entonces su llamada de enlace Butterknife debería verse así:
Enlace de documentación de Butterknife: http://jakewharton.github.io/butterknife/
Plug: Butterknife revolucionará tu desarrollo de Android. Considéralo.
Nota: Se puede lograr el mismo resultado sin el uso de la biblioteca externa Butterknife. Simplemente configure un OnClickListener en el diseño principal como se describe anteriormente.
fuente
En kotlin, podemos hacer lo siguiente. No es necesario iterar todas las vistas. Funcionará también para fragmentos.
fuente
Aquí hay otra variación en la respuesta de fje que aborda los problemas planteados por sosite.
La idea aquí es manejar las acciones hacia abajo y hacia arriba en el
dispatchTouchEvent
método de la Actividad . En la acción hacia abajo, tomamos nota de la vista enfocada actualmente (si la hay) y si el toque estaba dentro de ella, guardando esos dos bits de información para más adelante.En la acción ascendente, primero despachamos, para permitir que otra vista potencialmente se enfoque. Si después de eso, la vista enfocada actualmente es la vista enfocada originalmente, y el toque hacia abajo estaba dentro de esa vista, entonces dejamos el teclado abierto.
Si la vista enfocada actualmente es diferente de la vista enfocada originalmente y es una
EditText
, entonces también dejamos el teclado abierto.De lo contrario lo cerramos.
En resumen, esto funciona de la siguiente manera:
EditText
, el teclado permanece abiertoEditText
a otroEditText
, el teclado permanece abierto (no se cierra / vuelve a abrir)EditText
que no sea otroEditText
, el teclado se cierraEditText
para que aparezca la barra de acción contextual (con los botones cortar / copiar / pegar), el teclado permanece abierto, aunque la acción ARRIBA tuvo lugar fuera del focoEditText
(que se movió hacia abajo para dejar espacio para el CAB) . Sin embargo, tenga en cuenta que cuando toca un botón en el CAB, cerrará el teclado. Eso puede o no ser deseable; si desea cortar / copiar de un campo y pegar en otro, sería. Si quieres volver a pegar en el mismoEditText
, no lo sería.cuando el foco
EditText
está en la parte inferior de la pantalla y hace clic largo en algún texto para seleccionarlo, elEditText
foco se mantiene y, por lo tanto, el teclado se abre como lo desea, porque hacemos la verificación "tocar está dentro de los límites de la vista" en la acción hacia abajo , no la acción de arriba.fuente
es demasiado simple, solo haga que su diseño reciente se pueda hacer clic y se pueda enfocar con este código:
y luego escriba un método y un OnClickListner para ese diseño, de modo que cuando se toque el diseño superior se llame a un método en el que escribirá código para descartar el teclado. el siguiente es el código para ambos; // tienes que escribir esto en OnCreate ()
método llamado desde listner: -
fuente
La respuesta aceptada me parece un poco compleja para este simple requisito. Esto es lo que funcionó para mí sin ningún problema técnico.
fuente
NestedScrollView
diseños complejos o complejos, consulte la respuesta aceptada: stackoverflow.com/a/11656129/2914140 . Debe saber que otros recipientes pueden consumir toques.Hay un enfoque más simple, basado en el mismo problema del iPhone. Simplemente anule el diseño del fondo en el evento táctil, donde está contenido el texto de edición. Simplemente use este código en OnCreate de la actividad (login_fondo es el diseño raíz):
fuente
Método para mostrar / ocultar teclado virtual
Espero que te hayan sido útiles
fuente
Esta es la solución más fácil para mí (y elaborada por mí).
Este es el método para ocultar el teclado.
ahora establezca el atributo onclick del diseño principal de la actividad en el método anterior,
hideKeyboard
ya sea desde la vista Diseño de su archivo XML o escribiendo el código siguiente en la vista de Texto de su archivo XML.fuente
He refinado el método, coloque el siguiente código en alguna clase de utilidad de IU (preferiblemente, no necesariamente) para que se pueda acceder desde todas sus clases de Actividad o Fragmento para cumplir su propósito.
Luego, por ejemplo, diga que necesita llamarlo desde la actividad, llámelo de la siguiente manera;
aviso
Esto nos da la vista raíz del grupo actual (no debe haber configurado la identificación en la vista raíz).
Salud :)
fuente
Intenta poner stateHidden como tu
windowSoftInputMode
valor de actividadhttp://developer.android.com/reference/android/R.attr.html#windowSoftInputMode
Por ejemplo para su actividad:
fuente
Actividad
ScreenUtils
fuente
Simplemente agregue este código en la clase @Overide
fuente
En lugar de iterar a través de todas las vistas o anular dispatchTouchEvent.
¿Por qué no simplemente anular onUserInteraction () de la Actividad, esto asegurará que el teclado se cierre cada vez que el usuario toque fuera de EditText.
Funcionará incluso cuando EditText esté dentro de scrollView.
fuente
Obtuve esto trabajando con una ligera variante en la solución de Fernando Camarago. En mi método onCreate, adjunto un único onTouchListener a la vista raíz, pero envío la vista en lugar de la actividad como argumento.
En una clase de Utils separada es ...
fuente
Esto puede ser antiguo, pero conseguí que funcione implementando una clase personalizada
la mejor práctica aquí es crear una clase Helper y cada contenedor de diseños relativos / lineales debe implementar esto.
**** Tome nota que solo el contenedor principal debe implementar esta clase (para optimización) ****
e implementarlo así:
la palabra clave esto es para Actividad. así que si estás en un fragmento, usas como getActivity ();
--- aprobado si te ayuda ... --- aplaude Ralph ---
fuente
Esta es una versión ligeramente modificada de la respuesta de fje que en su mayoría funcionó perfectamente.
Esta versión usa ACTION_DOWN, por lo que realizar una acción de desplazamiento también cierra el teclado. Tampoco propaga el evento a menos que haga clic en otro EditText. Esto significa que al hacer clic en cualquier lugar fuera de EditText, incluso en otro clic, simplemente cierra el teclado.
fuente
view
yviewTmp
agetCurrentFocus()
, por lo que siempre tendrán el mismo valor.He hecho de esta manera:
Ocultar código del teclado :
Hecho
fuente