本文主要是介绍事件分发机制3-viewgroup的分发流程move,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
笔记之后整理
move分发流程还是要从viewgroup的dispatchTouchEvent方法看起
if (actionMasked == MotionEvent.ACTION_DOWN|| mFirstTouchTarget != null)
因为mFirstTouchTarget !=null 会进入语句 判断拦不拦截 不拦截继续
源码中move不会再分发事件了 mFirstTouchTarget不为null 直接走else
代码1boolean alreadyDispatchedToNewTouchTarget = false;
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;
代码2 if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
handled = true;
} else {
代码3 final boolean cancelChild = resetCancelNextUpFlag(target.child)
|| intercepted;
代码4 if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pointerIdBits)) {
handled = true;
}
if (cancelChild) {
if (predecessor == null) {
mFirstTouchTarget = next;
} else {
predecessor.next = next;
}
target.recycle();
target = next;
continue;
}
}
predecessor = target;
target = next;
}
}
只循环一次,代码1 alreadyDispatchedToNewTouchTarget = false;
所以在代码2判断时走else方法 在代码4的地方进行分发给 target.child
Target.child就是down事件中addTouchTarget(child, idBitsToAssign)的target
最后就交给view的dispatchTouchEvent
如何处理事件冲突 -- 只能在move的时候处理事件冲突
内部拦截 :子view处理事件冲突
假如父容器的interceptTouchEvent返回true
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
Intercepted = true就不会走事件分发的代码。disallowIntercept为false的话就不会走父容器的
onInterceptTouchEvent方法 所以需要改变disallowIntercept的值 requestDisallowInterceptTouchEvent
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
// We're already in this state, assume our ancestors are too
return;
}
if (disallowIntercept) {
mGroupFlags |= FLAG_DISALLOW_INTERCEPT;
} else {
mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
}
// Pass it up to our parent
if (mParent != null) {
mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
}
}
第一个move事件的目的是取消listview.cancel事件
第二个move事件 intercepted = true 不分发 走if 自己消费
父容器可以抢子view的时间 ,子view不可以抢父容器的事件
子view一旦拿到时间 再怎么处理由子view说的算
外部拦截:父容器处理冲突
这篇关于事件分发机制3-viewgroup的分发流程move的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!