版权声明:本文来自门心叼龙的博客,属于原创内容,转载请注明出处:https://blog.csdn.net/geduo_83/article/details/90145083
github源码下载地址:https://github.com/geduo83/android-touch-event
Android事件分发机制的探索与发现之View篇
Android事件分发机制的探索与发现之ViewGroup篇
Android事件分发机制的探索与发现之Activity篇
Android事件分发机制的探索与发现之总结篇
Android事件分发机制在实战开发中的应用之一
Android事件分发机制在实战开发中的应用之二
上一篇文章我们主要讲View MyButton的事件分发流程,这篇主要来分析MyLayout的事件分发流程,研究方法一样,通过改变返回值,来观察事件的分发流程
MyLayout的onInterceptTouchEvent方法
MyLayout其本质是一个ViewGroup,ViewGroup比View就多了一个事件拦截的方法onInterceptTouchEvent,因此我们MyLayout对的测试先从它的拦截方法开始
- 情况1:调用父类的同名方法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return super.onInterceptTouchEvent(ev);
}
其实我们上面已经测试过了,我们的测试MyButton的相关方法的时候,MyLayout的onInterceptTouchEvent方法调用的就是父类的同名方法,
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyButton dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
事件到达MyLayout onInterceptTouchEvent的方法后,调用了父类的同名方法super.onInterceptTouchEvent后,事件会继续传递给MyButton的dispatchTouchEvent 方法进行事件分发
- 情况2:返回false
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return false;
}
点击测试结果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyButton dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyButton onTouchEvent start:ACTION_DOWN
----------------------------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_UP
V/MYTAG: MyButton dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyButton onTouchEvent start:ACTION_UP
我们发现MyLayout的onInterceptTouchEvent方法返回false和调用父类的同名方法super.onInterceptTouchEvent方法,事件的传递流程都是一样的
- 情况3:返回ture
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return super.onTouchEvent(event);
}
点击测试结果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
--------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
如果返回true触摸事件不会继续传递给MyButton了,而直接就被MyLayout拦截掉了,并将事件传递给自己的onTouchEvent方法进行消费
好了,关于MyLayout的onInterceptTouchEvent方法我们彻底测试完毕了,我们不难得出结论:当onInterceptTouchEvent返回false和调用父类的同名方法的时候,触摸事件会继续往下传递,当返回true的时候该事件就被被拦截掉,并交给自己的onTouchEvent方法进行处理
MyLayout的onTouchEvent方法
- 情况1:调用父类的同名方法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return super.onTouchEvent(event);
}
注意了,为了便于测试我们让onInterceptTouchEvent返回true
测试结果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
--------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
通过测试日志我们可以发现,当MyLayout的onTouchEvent调用父类的同名方法,触摸事件会继续回传给MainActivity的onTouchEvent进行处理,其实在前面我们测试过了,当MyButton的onTouchEvent方法返回false和dispathTouchEvent方法返回false触摸事件都会回传给MyLayout的onTouchEvent方法,紧接着就继续回传给MainActivity的onTouchEvent方法
- 情况2:返回false
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return false;
}
测试结果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
---------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_MOVE
V/MYTAG: MainActivity onTouchEvent start:ACTION_MOVE
---------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
返回false和调用父类的同名方法,事件传递的流程都是一样的,触摸事件都回传给了MainActivity的onTouchEvent方法进行处理
- 情况3:返回true
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return true;
}
测试结果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
----------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout onTouchEvent start:ACTION_UP
返回true很简单,事件被自己消费掉了
好了,截止到线程关于MyLayout的onTouchEvent方法就分析完毕了,我们不难得出结论:MyLayout的onTouchEvent方法返回true事件就消费掉了,如果返回false和调用父类的同名方法super.onTouchEvent方法事件就会继续回传给MainActivity的onTouchEvent方法进行处理
MyLayout的dispatchTouchEvent方法
- 情况1:调用父类的同名方法
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout dispatchTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return super.dispatchTouchEvent(ev);
}
上面也都测试过了,如果MyLayout的dispatchTouchEvent调用了父类的同名方法则触摸事件会继续传递给它自己的onInterceptTouchEvent方法进行处理,测试日志如下:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
- 情况2:返回false
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout dispatchTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return false;
}
点击测试:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
--------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
返回false触摸事件直接就回传了给了MainActivity的onTouchEvent方法进行处理了
- 情况3:返回true
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout dispatchTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
点击测试结果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
----------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_MOVE
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_MOVE
----------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UP
返回true,触摸事件就直接被自己的dispatchTouchEvent方法消费掉了
好了,截止目前关于MyLayout的dispathTouchEvent方法就彻底分析完毕了,结论如下:MyLayout的dispatchTouchEvent方法调用父类的同名方法则事件会继续往下传递给自己的onInterceptTouchEvent方法,如果返回false则事件会回传给MainActivity的onTouchEvent方法进行处理,如果返回为true则就自行消费掉了
网友评论