事件的传递规则
一、点击事件(MotionEvent),当点击事件发生后,系统是如何将一个事件传递到view的过程,就是事件分发机制。
二、涉及到的方法:
@Override
public booleandispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
//注意:View只有继承ViewGroup,才有onInterceptHoverEvent方法
@Override
public booleanonInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public booleanonTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
三、理解:
一个根ViewGroup,当接收到(MotionEvent)事件时,会调用dispatchTouchEvent,如果它的onInterceptTouchEvent返回为true,则表示这个点击事件由当前的ViewGroup去处理,不会向子View传递,直接调用它的onTouchEvent去处理事件。如果onInterceptTouchEvent返回的是false,则表示向子View传递,子View会按照上面的逻辑重复判断,直到事件被消费掉。
四、总结的图(简易版)
五、3个方法的关系,用伪代码表现:
@Override
public booleandispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
booleanconsume=false;
if(onInterceptTouchEvent(event))
{
consume=onTouchEvent(event);
}
else{
consume=child.dispatchTouchEvent(event);
}
returnconsume;
}
六、传递过程:Activity--->window--->view
即:一个事件最开始一定传给Actvitiy,然后是window,然后是顶级的View,当顶级的View接收到,就开始了上述的时间分发机制,如果所有层的view的onTouchEvent都返回fasle,则表示所有的view都不处理这个事件,那么事件则按照反方向重新传递,最后会传递到activity的onTouchEvent方法。
七、总结
1、一个触摸事件指的是,从手指按下(down),到手指离开(up),当然也包括按下以后,滑动最后抬起的操作,都算是一个触摸事件。
2、正常情况下,一个事件只能由一个view拦截并且消耗。
3、View没有onInterceptTouchEvent方法,一旦有点击事件传递给它,那么它的onTouchEvent方法就会被调用
4、因为View没有onInterceptTouchEvent方法,所以,如果不想处理这个事件,就在onTouchEvent方法中返回false,那么父类基于这个事件,将不再向这个子View传递。
5、ViewGroup默认不拦截任何事件。也就是说你不重写onInterceptTouchEvent方法,事件就会默认向下传递。
6、View的onTouchEvent默认都会消耗事件的。除非它是不可点击的(clickble和longclickble都返回false)
7、View的enable(是否可用)属性不影响onTouchEvent的事件消耗。因为clickble或者
longclickble有一个返回true,它都会将事件消耗掉
8、Android中的window是一个抽象类,phonewindow是一个唯一实现window的实现类。
八、概念
八、根据这个说明,再来一个更加详细的图(原创)