backgroud
由于在《Android
进阶之光》中作者用了比较大的篇幅来介绍View
和ViewGroup
的源码,以理解关于事件分发机制的原理。且本人还没有去阅读源码,故而这里就直接摘要自己感觉重要的部分。毕竟还是不要误导他人的好。
View
和ViewGroup
的涉及方法
在了解了什么是事件分发后,我们还需要了解事件分发的3个重要方法。点击事件有3个重要的方法,它们分别是:
dispatchTouchEvent
(MotionEvent ev
)—用来进行事件的分发。onInterceptTouchEvent
(MotionEvent ev
)—用来进行事件的拦截,在dispatchTouchEvent()
中调用,需要注意的是View
没有提供该方法。onTouchEvent
(MotionEvent ev
)—用来处理点击事件,在dispatchTouchEvent()
方法中进行调用。
1. 点击事件由上而下的传递规则
当点击事件产生后会由 Activity
来处理,传递给PhoneWindow
,再传递给DecorView
,最后传递给顶层的ViewGroup
。
一般在事件传递中只考虑 ViewGroup
的 onInterceptTouchEvent
方法,因为一般情况下我们不会重写 dispatchTouchEvent()
方法。
对于根ViewGroup
,点击事件首先传递给它dispatchTouchEvent()
方法,如果该ViewGroup
的onInterceptTouchEvent()
方法返回true
,则表示它要拦截这个事件,这个事件就会交给它的onTouchEvent()
方法处理;
如果onInterceptTouchEvent()
方法返回false
,则表示它不拦截这个事件,则这个事件会交给它的子元素的dispatchTouchEvent()
来处理,如此反复下去。
如果传递给底层的View
,View
是没有子View
的,就会调用View
的dispatchTouchEvent()
方法,一般情况下最终会调用View
的onTouchEvent()
方法。
【注意】onInterceptTouchEvent()
方法默认返回false
,不进行拦截。如果想要让ViewGroup
拦截事件,那么应该在自定义的ViewGroup
中重写这个方法。
2. 点击事件由下而上的传递规则
当点击事件传给底层的View
时,如果其onTouchEvent()
方法返回true
,则事件由底层的View
消耗并处理;
如果返回false
则表示该View
不做处理,则传递给父View
的onTouchEvent()
处理;
如果父View
的onTouchEvent()
仍旧返回false
,则继续传递给该父View
的父View
处理,如此反复下去。