http://www.android100.org/html/201502/26/123262.html

首先从字面意思理解两个词

onTouchEvent:触发触摸事件

onInterceptTouchEvent:触发拦截触摸事件

通过查看源代码及类继承关系

onInterceptTouchEvent:是定义于ViewGroup里面的一个方法,此事件是用于拦截触摸事件的,ViewGroup(继承自View),一个View的Group,也就是我们的一个布局如LinerLayout,各个布局类都继承自ViewGroup;

onTouchEvent:是定义于View中的一个方法,处理传递到View的手势触摸事件。手势事件类型包括ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL等事件;

其中ViewGroup里的onInterceptTouchEvent默认返回值是false,这样touch事件会传递到View控件,ViewGroup里的onTouchEvent默认返回值是false;

View里的onTouchEvent默认返回值是true,当我们手指点击屏幕时候,先调用ACTION_DOWN事件,当onTouchEvent里返回值是true的时候,onTouch会继续调用ACTION_UP事件,如果onTouchEvent里返回值是false,那么onTouchEvent只会调用ACTION_DOWN而不调用ACTION_UP。

1、新建两个类LLayout , LView 如下

代码如下:
public class LLayout extends FrameLayout {// ViewGroup@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {Log.i("LTAG", "LLayout onInterceptTouchEvent");Log.i("LTAG", "LLayout onInterceptTouchEvent default return" + super.onInterceptTouchEvent(ev));return super.onInterceptTouchEvent(ev);}// View@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.i("LTAG", "LLayout onTouchEvent");Log.i("LTAG", "LLayout onTouchEvent default return" + super.onTouchEvent(event));return super.onTouchEvent(event);}
}
public class LView extends Button {// TextView <-- View@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.i("LTAG", "onTouchEvent");Log.i("LTAG", "onTouchEvent default return" + super.onTouchEvent(event));return super.onTouchEvent(event);}
}

2、修改布局文件为如下布局

代码如下:
 <com.touchpro.LLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><com.touchpro.LViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/app_name" />
</com.touchpro.LLayout>

(1)先点击界面中的按钮

(2)再点击界面中的其它区域

结论:LLayout 中 onInterceptTouchEvent 默认返回值为false,onTouchEvent 默认返回值为false,所以只调用了ACTION_DOWN事件;

LView中 onTouchEvent 默认返回值为true;调用了ACTION_DOWN,ACTION_UP 两个事件;

(3)修改LLayout中onInterceptTouchEvent返回值为true,再次运行代码:

结论:LLayout中onInterceptTouchEvent返回了true,对触摸事件进行了拦截,所以没有将事件传递给View,而直接执行了LLayout中的onTouchEvent事件;

(4)把LLayout中onInterceptTouchEvent返回值改为false,再把LView中的onTouchEvent改为返回false:

结论:由于将LView中onTouchEvent返回值修改为false,因此只执行了ACTION_DOWN,然后就到LLayout中执行onTouchEvent事件了;

ViewGroup里的onInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.

ViewGroup里的onTouchEvent默认值是false。

View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

View事件详解:
onTouch:一般需要调用setOnTouchListener方法,即可看到该方法。
默认返回false,如果返回true事件不在传送。对于view来说先调用ontouch在调用onClick(如果onTouch返回true,则onClick方法不执行)
onClick:点击事件

dispatchTouchEvent事件:当触摸任何一个控件,就一定会调用该控件的dispatchTouchEvent方法,

public boolean dispatchTouchEvent(MotionEvent event) {  if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&  mOnTouchListener.onTouch(this, event)) {  return true;  }  return onTouchEvent(event);
}  

如果调用了setOnTouchListener方法第一个条件为true,只要按钮没有被禁用第二个条件为true,第三个条件就比较关键了,mOnTouchListener.onTouch(this, event),其实也就是去回调控件注册touch事件时的onTouch方法。也就是说如果
我们在onTouch方法里返回true,就会让这三个条件全部成立,从而整个方法直接返回true。如果我们在onTouch方法里返回false,就会再去执行onTouchEvent(event)方法。

由上面可知,onClick的调用肯定是在onTouchEvent(event)方法中的。
我们都知道如果给一个控件注册了touch事件,每次点击它的时候都会触发一系列的ACTION_DOWN,ACTION_MOVE,ACTION_UP等事件。这里需要注意,如果你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。
简单的说,就是当dispatchTouchEvent在进行事件分发的时候,只有前一个action返回true,才会触发后一个action。

public boolean onTouchEvent(MotionEvent event) {  final int viewFlags = mViewFlags;  if (((viewFlags & CLICKABLE) == CLICKABLE ||  (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {  //只要按钮可以点击,就返回trueswitch (event.getAction()) {  case MotionEvent.ACTION_UP:  ...performClick();  ...break;}  return true;  }  return false;
}

ViewGroup 事件传递:
ViewGroup中的dispatchTouchEvent方法的源码

public boolean onInterceptTouchEvent(MotionEvent ev) {  return false;
}  
public boolean dispatchTouchEvent(MotionEvent ev) {  final int action = ev.getAction();  final float xf = ev.getX();  final float yf = ev.getY();  final float scrolledXFloat = xf + mScrollX;  final float scrolledYFloat = yf + mScrollY;  final Rect frame = mTempRect;  boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;  if (action == MotionEvent.ACTION_DOWN) {  if (mMotionTarget != null) {  mMotionTarget = null;  }  if (disallowIntercept || !onInterceptTouchEvent(ev)) {  //调用了onInterceptTouchEvent方法,它默认返回false,因此view控件的onClick才能执行。如果当前viewgroup需要处理事件,可以将其返回true。...}  }  ...
}

onTouchEvent 和 onInterceptTouchEvent 事件触摸相关推荐

  1. Android中 onTouchEvent() 与 onInterceptTouchEvent()事件的区别详解

    1.onTouchEvent:触发触摸事件 onInterceptTouchEvent:触发拦截触摸事件 通过查看源代码及类继承关系 onInterceptTouchEvent:是定义于ViewGro ...

  2. Android事件分发之ViewGroup篇 -- ViewGroup的dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent之间关系

    Android事件分发之ViewGroup篇(FatherViewGroup) – ViewGroup的dispatchTouchEvent.onTouchEvent.onInterceptTouch ...

  3. 浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解

    浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解 本篇文章小编为大家介绍,Android onTouchEvent 与 onInterceptTo ...

  4. android触摸事件触摸点坐标,Android开发——触摸事件TouchEvent详解及其应用

    2020.8.8 Activity的功能: 1.管理界面的生命周期 2.接收事件(触摸事件) 一.触摸事件传递解析 touch事件的传递.png 当手指按下时会首先调用onUserInteractio ...

  5. ios事件-触摸事件2(手势 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)

    ios事件-触摸事件2(手势 和 pointInSide().hitTest().touchesBegan().touchesMoved().touchesEnded().touchesCancell ...

  6. ios事件-触摸事件3(UIButton 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)

    ios事件-触摸事件3(UIButton 和 pointInSide().hitTest().touchesBegan().touchesMoved().touchesEnded().touchesC ...

  7. Android onTouchEvent 与 onInterceptTouchEvent的区别详解

    首先从字面意思理解两个词 onTouchEvent:触发触摸事件 onInterceptTouchEvent:触发拦截触摸事件 通过查看源代码及类继承关系 onInterceptTouchEvent: ...

  8. (转)Android ViewGroup的onInterceptTouchEvent()事件分析

    onInterceptTouchEvent()的机制: 1. down事件首先会传递到onInterceptTouchEvent()方法 2. 如果该ViewGroup的onInterceptTouc ...

  9. ScrollView的上下联动事件 触摸事件传递机制

    注意事项:1.当返回值为false的时候,触摸事件向下或者向子view传递: 2.当返回时间为true时:触摸事件不向下执行 常用事件的方法: dispatchTouchEvent(Acitivity ...

最新文章

  1. ./src/cuda.c:36: check_error: Assertion `0‘ failed
  2. 推荐系统之信息茧房问题
  3. 慕尼黑工业大学最新综述:深度神经网络中的不确定性
  4. 把javascript中的json对象传到action的list里的方法
  5. Python:Matplotlib 画曲线和柱状图(Code)
  6. HDU1256 画8【打印图案】
  7. java对机房有什么用_使用云终端建设的云机房相比传统机房有什么区别
  8. 福大第二学士学位计算机专业就业前景,福州大学省级重点学科介绍:计算机应用技术(081203)...
  9. Hive数据更新同时去重入门
  10. 基于Socket的.NET应用组件
  11. Python Socket模块实现服务端与客户端通信
  12. SaaS-HRM(2)数据库设计与前端框架(企业管理前后台)
  13. Photoshop插件-黑白(二)-脚本开发-PS插件
  14. 荣耀V8鸿蒙系统刷机包,华为荣耀V8原版rom系统刷机包_荣耀V8最新版升级包更新下载...
  15. SpringCloud OpenFeign调用第三方服务
  16. 国产ChatGPT命名图鉴
  17. 微信的原创保护机制到底是如何实现的?
  18. 好用到爆!IDEA 版 Postman 面世了,功能真心强大
  19. 穆斯林的葬礼-(爱情,是人类最美好的感情)
  20. 51.【Java String方法的小结】

热门文章

  1. 政务云平台建设与运营解决方案 PPT
  2. 掩码、通配符与反掩码
  3. 游戏开发完整学习路线
  4. matlab newff函数弃用了,matlab里面的newff函数怎么回事
  5. 疑难汉字(有读音有注释)
  6. 计算机原理(bilibili课程)
  7. 导出文件提示rpc服务器不可用,rpc服务器不可用怎么办 RPC服务器不可用解决方法有哪些...
  8. 扶桑号战列舰(单调栈)
  9. 劳动仲裁1——保姆级教程(打工人程序猿,维权少走弯路)
  10. NB-IOT联网通信