ViewGroup的TouchEvent的处理机制
来源:互联网 发布:linq 更新数据 编辑:程序博客网 时间:2024/06/08 12:33
触摸事件TouchEvent的传递路径:
Activity->Window->DecorView(DecorView即为一个ViewGroup)
ViewGroup中的dispatchTouchEvent源码
/* * * ViewGroup的dispatchTouchEvent中判断是否拦截事件部分逻辑代码 */ if (actionMasked == MotionEvent.ACTION_DOWN) { // 当接收到DOWN事件时,会执行重置FLAG_DISALLOW_INTERCEPT标记位, mFirstTouchTarget = null等操作 cancelAndClearTouchTargets(ev); resetTouchState();}// 判断是否拦截事件的实现逻辑final boolean intercepted;// 传入的为Down事件时ViewGourp一定会执行onInterceptTouchEvent(ev)方法询问是否需要拦截该Down事件// 传入的事件不为Down时, ViewGroup会判断当前事件序列的前一事件是否被子View消耗了, 若有子View消耗(即mFirstTouchTarget != null), 也有可能触发ViewGroup拦截该事件if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { // 若当前为Down事件时, FLAG_DISALLOW_INTERCEPT会被重置, 所以一定会执行if下中的语句 // 该标记位是子View在处理事件时通过parent.requestDisallowInterceptTouchEvent()设定, 用于阻止它的parent拦截下一个非Down事件 final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; if (!disallowIntercept) { intercepted = onInterceptTouchEvent(ev); ev.setAction(action); // restore action in case it was changed } else { // 如果不允许拦截, 则直接返回false, 将事件分发给子View intercepted = false; }} else { // 当传入的非Down事件 且 mFirstTouchTarget == null时ViewGoup将直接拦截该事件, 交由onTouchEvent()去处理, 若onTouchEvent()也为false则, 将事件抛给上级处理 intercepted = true;}
从源码中可以看出 , 当且仅当传入事件为down或当前序事件已被childView消耗(mFirstTouchTarget != null)时才有可能调用onInterceptTouchEvent()方法
(1) 同一个事件序列是从手指接触屏幕的那一刻起, 到手指离开屏幕的那一刻结束, 在这个过程中所产生的一系列事件, 这个事件序列以down事件开始, 中间含有数量不等的move事件, 最终以up事件结束。
(2)ViewGroup默认不拦截任何事件。
(3)View的onTouchEvent默认消耗事件(返回true),除非它是不可点击的(clickable和longClickable同时为false)。
(4)一般down事件都是由点击事件链中最底层的View消耗的。
(5)正常情况下, 一个事件序列(除了down外)只能被一个View消耗。
我们自定义View中一般ViewGroup是不拦截down事件的,当down之后的事件(move、up)传入该ViewGroup时,因为mFirstTouchTarget !=null(指向之前消耗down事件的child),故该ViewGroup会通过onInterceptTouchEvent()进行判断是否拦截该事件。若拦截,则该事件被当前ViewGroup消耗,此时mFirstTouchTarget ==null。当下一个事件传入时 if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null)不成立 ,所以后续事件将不通过onInterceptTouchEvent()判断,直接被拦截该ViewGroup拦截。
特殊情况:我们重写ViewGroup的dispatchTouchEvent时, 在down事件传入时调用
parent.requestDisallowInterceptTouchEvent(true),阻止其父容器拦截move和up事件, 然后在move传入该ViewGroup时某一条件下调用parent.requestDisallowInterceptTouchEvent(false), 此时后续事件可能被父容器拦截,不再传入该ViewGroup。
- ViewGroup的TouchEvent的处理机制
- View和ViewGroup的TouchEvent
- 触摸事件的分析与总结----TouchEvent处理机制
- android的TouchEvent事件机制
- Android TouchEvent处理机制
- viewgroup的touch事件处理机制
- TouchEvent分发过程二:ListView中TouchEvent的处理
- android各种触摸事件的处理,touchEvent
- Android开发中处理TouchEvent的林林总总
- ViewGroup的事件分发机制
- Android-ViewGroup的事件机制
- ViewGroup的事件分发机制
- ViewGroup的事件分发机制
- ViewGroup 的事件分发机制
- ViewGroup的事件传递机制
- 从源码角度解析TouchEvent的传递机制
- Android TouchEvent的传递
- TouchEvent事件的传递
- linux启动分析——init进程与app启动
- 04. 斜堆(Skew Heap)
- 《剑指offer》求二叉树的最小深度(非递归法)
- Windows路由表配置:双网卡同时上公司内外网
- 斐波拉契数列矩阵连乘(模板)
- ViewGroup的TouchEvent的处理机制
- org.apache.commons.lang.builder.ReflectionToStringBuilder类,用于将对象转换成字符串
- implement strStr()
- 我要通过
- windows环境下ElasticSearch5以上版本安装head插件
- 01. 选择、插入、冒泡排序
- nginx启动与配置
- 2017年-年中总结
- 杨澜:人工智能是镜子,反映欲望、人性和爱【智库2861】