В Андроиде метод
dispatchTouchEvent(event: MotionEvent)
с одинаковой сигнатурой есть в двух классах:
Activity
и
View
. Этот метод помогает доставить объект
MotionEvent
до
View
, которой он предназначен.
Когда пользователь дотрагивается до экрана в области запущенного приложения, система доставляет объект
MotionEvent
в активити. Вызывается метод
Activity.dispatchTouchEvent()
.
Activity.dispatchTouchEvent()
делегирует вызов в класс
Window, на котором вызывается
superDispatchTouchEvent()
.
Window
, в свою очередь, вызывает
dispatchTouchEvent()
на decor view, которая является первой view в иерархии, связанной с
Window
.
Decor View – это верхний
ViewGroup
в иерархии view, ассоциированной с
Window.
В классе
ViewGroup
метод
dispatchTouchEvent()
переопределен и имеет отличную реализацию от класса
View
, поэтому рассмотрим их отдельно.
ViewGroup.dispatchTouchEvent()
определяет, следует ли отправить ивент в одну из дочерних view или обработать в текущей
ViewGroup
:
1. Сначала вызывается метод
onInterceptTouchEvent()
. Если этот метод возвращает
false
, то ивент пробрасывается вниз по иерархии view, иначе
ViewGroup
обрабатывает ивент сама;
2. Проверяются координаты каждой дочерней view и координаты объекта
MotionEvent
. Если
MotionEvent
входит в границы дочерней view, то на ней вызывается метод
dispatchTouchEvent()
и объект
MotionEvent
переходит вниз по иерархии;
3 Если ни одна из дочерних view не подходит для передачи ивента, то текущая
ViewGroup
считается таргет-view и обрабатывает ивент.
View.dispatchTouchEvent()
вызывается только в том случае, когда текущая view уже определена как таргет-view ивента. Этот метод делает следующее:
1. Если view имеет
OnTouchListener
, то вызывается
OnTouchListener.onTouch()
с объектом
MotionEvent
в качестве параметра;
2. Если ивент не обработан листенером, то вызывается метод
View.onTouchEvent()
.