我们在面试的时候经常会被问到android事件分发机制,对于这个知识点其实也不算太难,关键在于不好理解,其实总结下来就两句话:
android事件分发过程:先由父类控件判断是否拦截(onInterceptTouchEvent() is true or false),拦截的话则执行该View的onTouchEvent()事件,否则则继续分发...
android事件处理过程:由子View先处理,如果子View不处理则交由父控件处理,否则一直向上传递。
举个例子:
这里有3个控件,分别实现了dispatchTouchEvent(),onInterceptTouchEvent(),onTouchEvent();
<? xml version= "1.0" encoding= "utf-8" ?>
<com.luck.anim.touch.MyLinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
android :orientation= "vertical" >
<com.luck.anim.touch.MyRelativeLayout
android :layout_width= "match_parent"
android :layout_height= "match_parent" >
<com.luck.anim.touch.MyButton
android :id= "@+id/my_btn"
android :layout_width= "match_parent"
android :layout_height= "wrap_content"
android :text= "自定义Button" />
</com.luck.anim.touch.MyRelativeLayout >
</com.luck.anim.touch.MyLinearLayout >
当我们都按默认返回的话,我点击MyButton时,执行的顺序是:
MyLinearLayout--->: dispatchTouchEvent MyLinearLayout--->: onInterceptTouchEvent
MyRelativeLayout--->: dispatchTouchEvent
MyRelativeLayout--->: onInterceptTouchEvent
MyButton--->: dispatchTouchEvent
MyButton--->: onTouchEvent
但我们在MyRelativeLayout中拦截此事件的话他的一个分发过程又是如何的呢?
MyLinearLayout--->: dispatchTouchEvent
MyLinearLayout--->: onInterceptTouchEvent
MyRelativeLayout--->: dispatchTouchEvent
MyRelativeLayout--->: onInterceptTouchEvent
MyRelativeLayout--->: onTouchEvent
MyLinearLayout--->: onTouchEvent
从这里可以看出当我们在某一层View中拦截掉事件的话,他不会继续向下分发了,而是执行自身View的3个函数了,但当我们并没有在当前View的onTouchEvent()事件做处理时,他还同时向上父级执行了onTouchEvent()事件。