onTouchEvent 和 onInterceptTouchEvent 事件触摸
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 事件触摸相关推荐
- Android中 onTouchEvent() 与 onInterceptTouchEvent()事件的区别详解
1.onTouchEvent:触发触摸事件 onInterceptTouchEvent:触发拦截触摸事件 通过查看源代码及类继承关系 onInterceptTouchEvent:是定义于ViewGro ...
- Android事件分发之ViewGroup篇 -- ViewGroup的dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent之间关系
Android事件分发之ViewGroup篇(FatherViewGroup) – ViewGroup的dispatchTouchEvent.onTouchEvent.onInterceptTouch ...
- 浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解
浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解 本篇文章小编为大家介绍,Android onTouchEvent 与 onInterceptTo ...
- android触摸事件触摸点坐标,Android开发——触摸事件TouchEvent详解及其应用
2020.8.8 Activity的功能: 1.管理界面的生命周期 2.接收事件(触摸事件) 一.触摸事件传递解析 touch事件的传递.png 当手指按下时会首先调用onUserInteractio ...
- ios事件-触摸事件2(手势 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)
ios事件-触摸事件2(手势 和 pointInSide().hitTest().touchesBegan().touchesMoved().touchesEnded().touchesCancell ...
- ios事件-触摸事件3(UIButton 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)
ios事件-触摸事件3(UIButton 和 pointInSide().hitTest().touchesBegan().touchesMoved().touchesEnded().touchesC ...
- Android onTouchEvent 与 onInterceptTouchEvent的区别详解
首先从字面意思理解两个词 onTouchEvent:触发触摸事件 onInterceptTouchEvent:触发拦截触摸事件 通过查看源代码及类继承关系 onInterceptTouchEvent: ...
- (转)Android ViewGroup的onInterceptTouchEvent()事件分析
onInterceptTouchEvent()的机制: 1. down事件首先会传递到onInterceptTouchEvent()方法 2. 如果该ViewGroup的onInterceptTouc ...
- ScrollView的上下联动事件 触摸事件传递机制
注意事项:1.当返回值为false的时候,触摸事件向下或者向子view传递: 2.当返回时间为true时:触摸事件不向下执行 常用事件的方法: dispatchTouchEvent(Acitivity ...
最新文章
- ./src/cuda.c:36: check_error: Assertion `0‘ failed
- 推荐系统之信息茧房问题
- 慕尼黑工业大学最新综述:深度神经网络中的不确定性
- 把javascript中的json对象传到action的list里的方法
- Python:Matplotlib 画曲线和柱状图(Code)
- HDU1256 画8【打印图案】
- java对机房有什么用_使用云终端建设的云机房相比传统机房有什么区别
- 福大第二学士学位计算机专业就业前景,福州大学省级重点学科介绍:计算机应用技术(081203)...
- Hive数据更新同时去重入门
- 基于Socket的.NET应用组件
- Python Socket模块实现服务端与客户端通信
- SaaS-HRM(2)数据库设计与前端框架(企业管理前后台)
- Photoshop插件-黑白(二)-脚本开发-PS插件
- 荣耀V8鸿蒙系统刷机包,华为荣耀V8原版rom系统刷机包_荣耀V8最新版升级包更新下载...
- SpringCloud OpenFeign调用第三方服务
- 国产ChatGPT命名图鉴
- 微信的原创保护机制到底是如何实现的?
- 好用到爆!IDEA 版 Postman 面世了,功能真心强大
- 穆斯林的葬礼-(爱情,是人类最美好的感情)
- 51.【Java String方法的小结】