View的事件分发机制一:事件分发概述

在android开发过程中,当在界面中有多个View可滑动时,且方向不一致的时候,可能会出现滑动冲突,那么如何去解决滑动冲突呢,它的基础就是View的事件分发机制。
View的事件分发所操作的对象就是MotionEvent,事件分发的过程就是对MotionEvent对象的分发过程,系统需要把这个MotionEvent对象下发到某个具体的View上进行处理。在MotionEvent对象分发的过程中涉及到三个函数,

1:dispatchTouchEvent
2:onInterceptTouchEvent
3:onTouchEvent


dispatchTouchEvent

这个函数的功能从名字上面就可以看出来,是用来进行事件的分发,当一个事件被传递到某个View上时,这个View上的dispatchTouchEvent函数就会被调用,它的返回值取决于当前View的onTouchEvent函数的返回值和子View的dispatchTouchEvent的返回值。如果返回值为true表示这个事件被当前view消费掉,返回false表示当前VIew无法处理这个事件。


onInterceptTouchEvent

这个函数在dispatchTouchEvent内部被调用,判断当前这个View是否决定拦截这个事件,如果当前View拦截了这个事件,那么事件就不会继续向下传递(如果有子View的话),并且在同一个事件序列中这个函数不会被再调用,且同一个事件序列中的接下来事件都会交给这个View处理。


onTouchEvent

这个函数在dispatchTouchEvent中调用,用来处理事件,返回true表示消费了当前事件,返回false表示无法处理这个事件,那么在接下来的同一个时间序列中,当前View无法再接受到事件,且这个View会将这个事件上传到它的上级,由他的上级来处理。


三者的关系描述

public boolean dispatchTouchEvent(MotionEvent ev){
boolean consume = false;
if(onIntercepterTouchEvent(ev)){
consume = onTouchEvent(ev);
}
else{
consume = child.dispatchTouchEvent(ev);
}
return consume;
}

对于一个根ViewGroup来书,当事件来临的时候,首先传递给它,然后它的dispatchTouchEvent就会被调用,如果这个onIntercerptTouchEvent返回true,表示它要拦截这个事件,接着这个事件就会交给它的onTouchEvent处理;如果onInterceptTouchEvnet返回false,表示不拦截这个事件,那么这个事件就会下发到它的子View,接着子View的dispatchEvent就会被调用,这样递归下去直到事件最终被处理。


如果一个View同时设定了OnTouchListener.onTouch,View.onTouchEvent,OnClickListener.onClick

这三个函数的优先级:onTouch>onTouchEvent>onClick.
如果onTouch返回了true,则onTouchEvent根本不会被调用,若onTouch返回了false,onTouchEvent方法才有能被调用。onClick是由View.perform函数调用的,perform函数是在OnTouchEvent中被调用的,所以说onClick的优先级最低。


事件在Activity,Window,View中的传递顺序

当发生一个事件时,先交给Activity,再交给Window,最后window再交给顶级View,事件到了顶级View之后,就会按照事件分发机制来分发事件。这里事件的下发和当View无法处理事件的上传过程是一个逆过程。举个例子:当屏幕上发生了一次点击事件,系统会将这个事件交给最底层的某个View来处理,但是这个View的onTouchEvent中返回了fasle即它无法处理这个事件,那这个时候怎么办呢,最简单的做法就是原路返回,交给之前下发事件给它的父View,如果这个父View也无法处理这个事件,则继续上传。如果都不能处理的话,最后就会交给Activity,由Activity的onTouchEvent 来处理。

你可能感兴趣的:(android,android开发,移动开发)