No estoy preguntando cómo manejar eventos táctiles, pero ¿qué está sucediendo detrás de escena? Si hay varios widgets anidados, ¿en qué orden ven los eventos? ¿El desarrollador tiene algún control sobre eso? Idealmente, me gustaría un documento sobre el tema.¿Cómo se envían los eventos de Android touch?
Respuesta
Desde el punto de vista de la actividad:
eventos táctiles se entregan primero en Activity.dispatchTouchEvent. Es donde puedes atraparlos primero.
Aquí se envían a la ventana, donde atraviesan la jerarquía de vistas, de manera que los widgets que se dibujan al final (sobre otros widgets) tienen la oportunidad de procesarlos en View.onTouchEvent primero. Si alguna Vista devuelve verdadero en onTouchEvent, el recorrido se detiene y otras Vistas no reciben evento táctil.
Finalmente, si ninguna Vista consume el toque, se envía a Activity.onTouchEvent.
Eso es todo su control. Y es lógico que lo que ves dibujado sobre otra cosa, tenga la oportunidad de procesar el evento táctil antes que algo dibujado debajo de él.
Echemos un vistazo a un ejemplo visual.
Cuando se produce un evento de contacto, en primer lugar a todos es notificado del evento, a partir de la actividad y va hasta el final a la vista en la parte superior. Luego, todos tienen la oportunidad de manejar el evento, comenzando con la vista en la parte superior y volviendo a la actividad. Entonces, la Actividad es la primera en enterarse y la última en tener la oportunidad de manejarlo.
si la actividad o algún ViewGroup quiere manejar el evento táctil de inmediato (y no le dan al otro por la línea de la oportunidad en ello) entonces, sólo se puede volver true
en su onInterceptTouchEvent()
.
Si una vista (o un grupo de visualización) tiene un OnTouchListener
, el evento táctil se maneja con OnTouchListener.onTouch()
. De lo contrario, es manejado por onTouchEvent()
. Si onTouchEvent()
devuelve true
para cualquier evento táctil, el manejo se detiene allí. Nadie más en el futuro tiene la oportunidad de hacerlo.
explicación más detallada
El diagrama anterior hace las cosas un poco más sencillo de lo que realmente son. Por ejemplo, entre la actividad y el grupo de visualización A (el diseño raíz) también están la ventana y el decorado. Los dejé arriba porque generalmente no tenemos que interactuar con ellos. Sin embargo, los incluiré a continuación. La siguiente descripción sigue un evento táctil a través del código fuente. Puede hacer clic en un enlace para ver el código fuente real.
- La actividad de
dispatchTouchEvent()
se notifica de un evento táctil. El evento táctil se transfiere comoMotionEvent
, que contiene las coordenadas x, y, la hora, el tipo de evento y otra información. - El evento táctil se envía al
superDispatchTouchEvent()
de la ventana.Window
es una clase abstracta. La implementación real esPhoneWindow
. - El siguiente en la fila para recibir la notificación es DecorView's
superDispatchTouchEvent()
.DecorView
es lo que maneja la barra de estado, la barra de navegación, el área de contenido, etc. It is actually just aFrameLayout
subclass, que a su vez es una subclase deViewGroup
. - El siguiente para recibir la notificación (corríjame si me equivoco) es la vista de contenido de tu actividad. Eso es lo que establece como el diseño raíz de su actividad en xml cuando crea el diseño en el Editor de diseño de Android Studio. Entonces, ya sea que elija
RelativeLayout
,LinearLayout
oConstraintLayout
, todas son subclases deViewGroup
. Y ViewGroup recibe una notificación del evento táctil endispatchTouchEvent()
. Este es el ViewGroup A en mis diagramas arriba. ViewGroup
notify any children tiene el evento táctil, incluyendo cualquierViewGroup
niños. Esto es ViewGroup B en mis diagramas arriba.- En cualquier parte del camino, un
ViewGroup
puede short-circuit el proceso de notificación devolviendotrue
paraonInterceptTouchEvent()
. - Suponiendo que no
ViewGroup
corta las notificaciones, el final natural de la línea para las notificaciones es cuando se llama a la vistadispatchTouchEvent()
. - Ahora es el momento para comenzar a manejar los eventos. If there is an
OnTouchListener
, entonces tiene la primera oportunidad de manejar el evento táctil cononTouch()
. Otherwise, la VistaonTouchEvent()
se encarga de manejarlo. - Ahora todos los ViewGroups recursivamente arriba de la línea tienen la oportunidad de manejar el evento táctil de la misma manera que lo hizo
View
. Aunque, no indicarlo en el diagrama anterior, unViewGroup
es una subclaseView
, así que todo lo descrito acercaOnTouchListener.onTouch()
yonTouchEvent()
también se aplica a ViewGroups. - Finally, si nadie más lo quería, la actividad también tiene la última oportunidad para controlar el evento con
onTouchEvent()
.
FAQ
Cuándo alguna vez necesitará anular dispatchTouchEvent()
?
Probablemente no sea necesario, a menos que necesite hacer un enrutamiento adicional que no ocurre de forma predeterminada. Para supervisar las notificaciones de eventos táctiles, puede anular onInterceptTouchEvent()
.
¿Cuándo tendría que anular alguna vez onInterceptTouchEvent()
?
Si solo quiere espiar las notificaciones táctiles que están entrando, puede hacerlo aquí y devolver false
.
Sin embargo, el principal propósito de anular este método es dejar que el ViewGroup manejar un determinado tipo de evento táctil mientras que dejan el niño a manejar otro tipo. Por ejemplo, un ScrollView
hace esto para manejar el desplazamiento mientras deja que su hijo maneje algo así como un clic de botón. Por el contrario, si la vista secundaria no quiere que su padre robe su evento táctil, puede llamar al requestDisallowTouchIntercept()
.
¿Cuáles son los tipos de eventos táctiles?
Los principales son
ACTION_DOWN
- Este es el comienzo de un evento de toque. Siempre debe devolvertrue
para el eventoACTION_DOWN
enonTouchEvent
si desea manejar un evento táctil. De lo contrario, no recibirá más eventos entregados a usted.ACTION_MOVE
- Este evento se dispara continuamente a medida que mueve el dedo por la pantalla.ACTION_UP
- Este es el último evento de un evento táctil.
Un finalista es ACTION_CANCEL
. Se llama a esto si un ViewGroup en el árbol decide interceptar el evento táctil.
Puede ver los otros tipos de MotionEvents here. Dado que Android es multitáctil, los eventos también se disparan cuando otros dedos ("punteros") tocan la pantalla.
estudio adicional
- Android onTouchEvent Part 1, Part 2 y Part 3 (vídeo de YouTube - buen resumen de algunos de los enlaces siguientes)
- Mastering the Android Touch System (vídeo a fondo por Google Developer)
- Android UI Internal : Pipeline of View's Touch Event Handling
- Managing Touch Events in a ViewGroup (documentos de Android)
- Input Events (Android d ocs)
- Gestures and Touch Events
- 1. ¿Los dispositivos Android/webOS admiten eventos Javascript multi-touch?
- 2. Eventos Slow JavaScript touch en Android
- 3. Android ¿Cómo se envían múltiples contactos se adjuntan en un único archivo .vcf y se envían al correo?
- 4. ¿Cómo se envían los comandos AT GSM utilizando python?
- 5. Delegados vs. eventos en Cocoa Touch
- 6. ¿Cómo envían los zombies el correo?
- 7. ¿Cómo maneja Android los eventos GUI?
- 8. ¿Cómo se envían correos masivos desde ASP.NET?
- 9. Android Vibrate on touch?
- 10. ¿Se envían elementos de formulario ocultos?
- 11. Sencha Touch 2 - Android Performance
- 12. Sencha Touch 2 android performance
- 13. Cómo manejar los eventos ButtonField y BitmapField Click (Touch) en Blackberry Storm?
- 14. Cómo se asignan los eventos en .NET
- 15. javascript internals: cómo se implementan los eventos?
- 16. ¿Puedo escuchar los eventos táctiles de Android?
- 17. ¿Qué datos se envían a Google Analytics?
- 18. Long Touch en un surfaceView (android)
- 19. ¿Todos los servidores IRC envían 005 RPL_ISUPPORT?
- 20. eventos de iPad touch en <video> etiqueta
- 21. cómo obtener los eventos de searchview en android
- 22. ¿Cómo se envían los datos de entrada sin procesar en una prueba funcional de Rails?
- 23. ¿Se envían datos JSONP vs. JSON?
- 24. Android Touch Evento que determina la duración
- 25. Android: ¿Cómo llamar a Touch solo después de un onLongClick?
- 26. ¿Los datos se envían a Google cuando se utiliza la API de visualización de Google?
- 27. Los paquetes de RTP no se envían ni se reciben con mjsip
- 28. HTML ¿Por qué los botones en los formularios envían datos?
- 29. ¿Cómo funcionan los recursos de limpieza de Sencha Touch 2?
- 30. C#: ¿Cómo se envían los mensajes OK o Cancel return from dialogs when not using buttons?
¿Tiene algún tipo de documento que describe esto? – DJClayworth
Acerca del envío: Puedo leer el código fuente y los comentarios de la función. Acerca del orden de vista transversal: lo he leído en algún documento, sin duda en developer.android.com, pero no puedo decir exactamente ahora. –
De todos modos, buen comienzo: http://developer.android.com/guide/topics/ui/ui-events.html –