ViewGroup事件分发
来源:互联网 发布:linux删除多个文件命令 编辑:程序博客网 时间:2024/05/18 19:19
ViewGroup继承自View从写了父类的dispatchTouchEvent而且多了一个onInterceptTouchEvent方法此方法代表是否拦截此事件的分发
// Check for interception. final boolean intercepted; if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; if (!disallowIntercept) { intercepted = onInterceptTouchEvent(ev); ev.setAction(action); // restore action in case it was changed } else { intercepted = false; } } else { // There are no touch targets and this action is not an initial down // so this view group continues to intercept touches. intercepted = true; }
当我们按下的时候回来到这里,首先会执行onInterceptTouchEvent判断是否拦截,而disallowIntercept代表不允许拦截默认为false我们也可以通过方法设置disallowIntercept的值来达到拦截目的,onInterceptTouchEvent默认返回false,我们可以通过重写这个方法达到拦截目的。
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) { // Child wants to receive touch within its bounds. mLastTouchDownTime = ev.getDownTime(); if (preorderedList != null) { // childIndex points into presorted list, find original index for (int j = 0; j < childrenCount; j++) { if (children[childIndex] == mChildren[j]) { mLastTouchDownIndex = j; break; } } } else { mLastTouchDownIndex = childIndex; } mLastTouchDownX = ev.getX(); mLastTouchDownY = ev.getY(); newTouchTarget = addTouchTarget(child, idBitsToAssign); alreadyDispatchedToNewTouchTarget = true; break; }我们直接掉到上面那段代码,此段代码也在dispatchTouchEvent方法中,我们主要关心的是dispatchTransformedTouchEvent方法而在此方法中发现了下面两行代码
if (child == null) { handled = super.dispatchTouchEvent(event); } else { handled = child.dispatchTouchEvent(event); }当我们child为空时,也就是把我们上网viewgroup当成view处理,调用suoer.dispatchTouchEvent当child不为空时也就调用子类的dispatchTouchEvent,可以从源码看出disTransformedTouchEvent的调用在一个for循环中,因为viewgroup并不一定一个孩子当dispatchtransformTouchevent返回为true时,会调用newTouchTarget=addTouchTarget(...)
private TouchTarget addTouchTarget(@NonNull View child, int pointerIdBits) { final TouchTarget target = TouchTarget.obtain(child, pointerIdBits); target.next = mFirstTouchTarget; mFirstTouchTarget = target; return target; }在addTouchTarget方法中,会给mFirstTouchTarget赋值,也就是child赋值给它。而当我们的move或up方法进来时当mFirstTouchTarget不为空时,会判断完是否拦截然后直接走下面的代码,而当mfirstTouchTargrt为空时直接走下面的代码
if (mFirstTouchTarget == null) { // No touch targets so treat this as an ordinary view. handled = dispatchTransformedTouchEvent(ev, canceled, null, TouchTarget.ALL_POINTER_IDS); } else { // Dispatch to touch targets, excluding the new touch target if we already // dispatched to it. Cancel touch targets if necessary. TouchTarget predecessor = null; TouchTarget target = mFirstTouchTarget; while (target != null) { final TouchTarget next = target.next; if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) { handled = true; } else { final boolean cancelChild = resetCancelNextUpFlag(target.child) || intercepted; if (dispatchTransformedTouchEvent(ev, cancelChild, target.child, target.pointerIdBits)) { handled = true; }
而当执行up时mFirstTouchTarget清空resetTouchState()--->clearTouchTargets()然年就被清空了
由上总结,当我们拦截down事件时,那么mFirstTouchTarget就为空了,子view就一直不会响应触摸事件,而要想给mFirstTouchTarget赋值就必须在Down中并且子view 的dispatchtouchevent返回true
在子类中重写dispatchTouchEvent中设置getParent().requestDisallowInterceptTouchEvent(boolean disallowIntercept)阻止父类拦截触摸事件intercept=false,这句话要在super.dispatchTouchEvent()之前
阅读全文
0 0
- android 事件分发 ViewGroup
- ViewGroup的事件分发
- ViewGroup事件分发机制
- ViewGroup事件分发处理
- ViewGroup事件分发
- ViewGroup事件分发
- ViewGroup事件分发
- ViewGroup的事件分发
- 事件分发(ViewGroup)
- viewGroup事件分发记录
- ViewGroup事件分发
- ViewGroup事件分发
- 事件分发机制---ViewGroup
- ViewGroup事件分发机制
- ViewGroup 事件分发
- ViewGroup的事件分发机制
- Android ViewGroup事件分发机制
- Android ViewGroup事件分发机制
- Win2008 r2+oracle rac 11.2.01+starwind 安装手册
- Asteroids!(bfs)
- stringcharbyteslength
- 【BZOJ4034】树上操作(HAOI2015)-树链剖分
- HORNER(霍纳)法则的C实现以及算法比较 2.10
- ViewGroup事件分发
- java编译中可能遇到的问题
- Ubuntu Server 16.04 安装tomcat8
- Tair java c++客户端配置使用
- Juery新增节点之后事件绑定无效
- get_brand_wcpay_request:fail,微信公众号支付的那点坑
- Adobe Acrobat Pro 2017 避免更新
- 将自定义消息发给所有顶层窗口(MFC)
- STM32定时器(TIM)概论