事件分发机制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说的算

 

外部拦截:父容器处理冲突

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值