1.2 事件分发的本质
答:将点击事件(MotionEvent)传递到某个具体的View & 处理的整个过程
1.3 事件在哪些对象之间进行传递?
答:Activity、ViewGroup、View
1.4 事件分发的顺序
即 事件传递的顺序:Activity -> ViewGroup -> View
1.从上可知,要想充分理解Android分发机制,本质上是要理解:
1.1 Activity对点击事件的分发机制
MotionEvent
View触摸事件通过MotionEvent来表示,主要分为:
1、ACTION_DOWN:手指按下
2、ACTION_UP:手指抬起
3、ACTION_MOVE:手指移动
4、ACTION_CANCEL:非正常取消
activity事件分发源码
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction(); (1)
}
//window的dispatchTouchEvent方法返回为true时,该方法返回true,否者执行onTouchEvent方法
if (getWindow().superDispatchTouchEvent(ev)) { (2)
return true;
}
return onTouchEvent(ev);
}
1.2 ViewGroup对点击事件的分发机制
1.3 View对点击事件的分发机制
1.5 事件分发过程由哪些方法协作完成?
答:dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()
完整图如下
![](https://img.haomeiwen.com/i1848495/06cc58cf593066d9.jpg)
-
onInterceptTouchEvent返回值true表示事件拦截, onTouch/onTouchEvent 返回值true表示事件消费。
-
触摸事件先交由Activity.dispatchTouchEvent。再一层层往下分发,当中间的ViewGroup都不拦截时,进入最底层的View后,开始由最底层的OnTouchEvent来处理,如果一直不消费,则最后返回到Activity.OnTouchEvent。
-
ViewGroup才有onInterceptTouchEvent拦截方法。在分发过程中,中间任何一层ViewGroup都可以直接拦截,则不再往下分发,而是交由发生拦截操作的ViewGroup的OnTouchEvent来处理。
-
子View可调用requestDisallowInterceptTouchEvent方法,来设置disallowIntercept=true,从而阻止父ViewGroup的onInterceptTouchEvent拦截操作。
OnTouchEvent由下往上冒泡时,当中间任何一层的OnTouchEvent消费该事件,则不再往上传递,表示事件已处理。 -
如果View没有消费ACTION_DOWN事件,则之后的ACTION_MOVE等事件都不会再接收。
只要View.onTouchEvent是可点击或可长按,则消费该事件. -
onTouch优先于onTouchEvent执行,上面流程图中省略,onTouch的位置在onTouchEvent前面。当onTouch返回true,则不执行onTouchEvent,否则会执行onTouchEvent。onTouch只有View设置了OnTouchListener,且是enable的才执行该方法。
总结一下:
对于 dispatchTouchEvent,onTouchEvent,return true是终结事件传递。return false 是回溯到父View的onTouchEvent方法。
ViewGroup 想把自己分发给自己的onTouchEvent,需要拦截器onInterceptTouchEvent方法return true 把事件拦截下来。
ViewGroup 的拦截器onInterceptTouchEvent 默认是不拦截的,所以return super.onInterceptTouchEvent()=return false;
View 没有拦截器,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent。
网友评论