图片来源于网络
View的事件分发机制
,这个是Android面试
的常客。在这篇博客当中聊聊我知道的View的事件分发机制
,希望对看文章的小伙伴有所帮助。
点击事件的分发机制
点击事件的本质,就是关于MotionEvent
事件分发的过程,具体是当一个MotionEvent
产生之后,Android
系统需要将这个事件传递给一个具体的View
,这个传递的过程就是分发过程,也就是我们说的分发机制。
点击事件的重要组成方法
-
dispatchTouchEvent
; -
onInterceptTouchEvent
; -
onTouchEvent
。
dispatchTouchEvent
该方法是用来进行事件的分发。如果事件能够传递给当前View
,那么该方法一定是调用过了。改方法返回的结果受到当前View
的onTouchEvent
和下一级的View
的dispatchTouchEvent
方法影响,表示要不要消耗当前的事件。
onInterceptTouchEvent
该方法是用来判断是否要拦截某个事件。如果当前的View
拦截了某个事件,那么在同一个事件的序列当中,这个方法不会被再次调用,返回的结果表示是否拦截当前的事件。
onTouchEvent
在dispatchTouchEvent
方法中调用,用来处理点击事件。返回结果表示是否消耗当前的事件,如果不消耗,会在同一个序列中,当前View
无法再次接收到事件。
dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent的区别
对于一个根ViewGroup
来说,点击事件产生后,首先传递给它,第一时间会调用dispatchTouchEvent
,如果这个ViewGroup
的onInterceptTouchEvent
- 返回
true
表示要拦截当前的事件,这个事件就会被ViewGrop
处理,接着ViewGroup
的onTouchEvent
会被调用; - 返回
false
表示不拦截当前事件,这个事件就会被传递给子元素,接着子元素会走dispatchTouchEvent
,也是同样的判断,直到事件被最终处理。
事件传递顺序
事件传递的顺序是:Activity
->Window
->View
。
可以这样理解:
- 事件总是先传递给Activity;
- Activity再传递给Window;
- 最后Window再传递给顶级View。
- 顶级View接收到事件后,就会按照事件分发机制去分发事件。
需要考虑一种情况,如果一个View的onTouchEvent返回false,那么它的父容器的onTouchEvent将会被调用,依此类推。
如果所有的元素都不处理这个事件,那么这个事件将会最终传递给Activity处理,即Activity的onTouchEvent方法会被调用。