点击事件的事件分发,就是对MotionEvent事件的分发过程,即当一个MotionEvent产生了以后,系统需要把这个事件传递给一个具体的View。
ViewGroup有该拦截方法;View并没有拦截方法,不存在分发,只能在onTouchEvent方法中进行处理消费或者不消费。
点击事件的分发过程由三个方法共同完成:
1.dispatchTouchEvent
public boolean dispatchTouchEvent(MotionEvent ev)
用来进行事件的分发。事件传递给一个View,这个View的dispatchTouchEvent方法就一定会被调用。
返回值表示是否消费了当前事件。
返回true可能是View本身的onTouchEvent方法消费,也可能是子View的dispatchTouchEvent方法中消费,本次的事件终止。
返回false表示View及子View均没有消费事件,将调用父View的onTouchEvent方法。
2.onInterceptTouchEvent
public boolean onInterceptTouchEvent(MotionEvent event)
在 dispatchTouchEvent 方法的内部调用,用来判断是否拦截某个事件,ViewGroup有该拦截方法,View并没有拦截方法。
返回true表示拦截了事件,那么事件将不再向下分发而是调用View本身的onTouchEvent方法。
返回false表示不做拦截,事件将向下分发到子View的dispatchTouchEvent方法。
3.onTouchEvent
public boolean onTouchEvent(MotionEvent event)
真正对MotionEvent进行处理或者说消费的方法。在dispatchTouchEvent进行调用。
返回true表示事件被消费,本次的事件终止。
返回false表示事件没有被消费,将调用父View的onTouchEvent方法。
View事件分发机制小结:
没有拦截的情况下,将逐级向下分发,直到最末端的子View,子View的onTouchEvent优先处理,不处理时则逐级回调父级的onTouchEvent方法。
有拦截的情况下,事件不再向下传递。由拦截的View本身的onTouchEvent处理,如该View未消费掉事件,则调用父级View的onTouchEvent方法处理。
补充:
MotionEvent有下面两种:
单击操作:ACTION_DOWN -> ACTION_UP
点击后滑动一段距离,再抬起:ACTION_DOWN -> ACTION_MOVE -> ... -> ACTION_MOVE -> ACTION_UP。
onTouchEvent中,如果不消耗ACTION_DOWN,则在同一个事件序列中,当前View再也无法接收到该事件的后续事件(ACTION_MOVE,ACTION_UP等)。如果消耗了ACTION_DOWN,则还可以消耗ACTION_MOVE,ACTION_UP等。
网友评论