Первый класс, который получает touch event – это
Activity
. Путь от activity вниз по иерархии оповещает ViewGroup
на каждом уровне. После достижения таргет-view ивент идет вверх по иерархии. На этом пути каждая из ViewGroup
может обработать ивент. Когда ивент обработан таргет-view или одной из ViewGroup
, он больше не доставляется на обработку следующим ViewGroup
.Реализовано это поведение следующим образом:
1. Сначала вызывается Activity.dispatchTouchEvent(). Этот метод делегирует вызов в decor view.
2. Ивент идет вниз по иерархии
ViewGroup
, начиная от decor view.3. На каждом уровне вызывается метод ViewGroup.dispatchTouchEvent(), который проверяет результат вызова onInterceptTouchEvent() в текущей
ViewGroup
.4. Если
onInterceptTouchEvent()
возвращает true
, то происходит короткое замыкание. Ивент перестает спускаться по иерархии и текущая ViewGroup
получает возможность первой обработать ивент. Если ViewGroup
не обрабатывает ивент, то он поднимается по иерархии.5. Если
onInterceptTouchEvent()
возвращает false
, то ивент спускается на следующий уровень, пока не доходит до таргет-view.6. На таргет-view вызывается метод
dispatchTouchEvent()
, который вызывает OnTouchListener.onTouch()
, если листенер задан. Если ивент не обработан листенером, то вызывается View.onTouchEvent()
.7. Если таргет-view не обработала ивент, то он поднимается по иерархии, пока не будет обработан или пока не достигнет activity.
ViewGroup
– наследник класса View
, поэтому обработка ивента на шаге 4 реализована также, как на шаге 6. Т.е. сначала вызывается OnTouchListener.onTouch()
, затем ViewGroup.onTouchEvent()
.