Как работает метод dispatchTouchEvent()?

В Андроиде метод 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().