版权声明:本文来自门心叼龙的博客,属于原创内容,转载请注明出处: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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWNV/MYTAG: MyButton dispatchTouchEvent start:ACTION_DOWNV/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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWNV/MYTAG: MyButton dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyButton onTouchEvent start:ACTION_DOWN----------------------------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UPV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UPV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_UPV/MYTAG: MyButton dispatchTouchEvent start:ACTION_UPV/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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onTouchEvent start:ACTION_DOWNV/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN--------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UPV/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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onTouchEvent start:ACTION_DOWNV/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN--------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UPV/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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onTouchEvent start:ACTION_DOWNV/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN---------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_MOVEV/MYTAG: MainActivity onTouchEvent start:ACTION_MOVE---------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UPV/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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN----------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UPV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UPV/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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
  • 情况2:返回false
@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {        Log.v(TAG,"MyLayout dispatchTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));        return false;}

点击测试:

V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWNV/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN--------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UPV/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_DOWNV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN----------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_MOVEV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_MOVE----------------------------------------------------------V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UPV/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UP

返回true,触摸事件就直接被自己的dispatchTouchEvent方法消费掉了
好了,截止目前关于MyLayout的dispathTouchEvent方法就彻底分析完毕了,结论如下:MyLayout的dispatchTouchEvent方法调用父类的同名方法则事件会继续往下传递给自己的onInterceptTouchEvent方法,如果返回false则事件会回传给MainActivity的onTouchEvent方法进行处理,如果返回为true则就自行消费掉了

更多相关文章

  1. 关于Android(安卓)Fragment生命周期以及其他方法的调用执行顺序
  2. Android(安卓)动态创建Drawable selector
  3. Android底层字符传递给上层应用举例
  4. Android(安卓)View的onClick回调机制
  5. android滑动事件监听
  6. 一步一步学android之事件篇——长按事件
  7. 加快Android(安卓)Stduio编译速度方法之一
  8. Android的ViewPager中移除Fragment
  9. 【Android】结束活动退出程序的方法

随机推荐

  1. android使用Intent操作拨打号码发送短信
  2. AsyncTask的使用
  3. android App Widgets
  4. android 开发之坑系列_实体序列化问题
  5. 第一天学习Android的一些笔记
  6. 【HR小时制】如何获取Android系统时间的
  7. android好帖子
  8. Android ListView 滚动加载数据
  9. Andriod开发教程 怎么导入现有的Android
  10. Error:(16, 0) Gradle DSL method not fo