Android事件分发机制总结

事件分发机制:
一个大致的布局:

<ViewGroup1>
    <ViewGroup2>
        <View/>
    </ViewGroup2>
</ViewGroup1>

ViewGroup中有事件分发机制如下:
首先会执行dispatchTouchEvent(MotionEvent ev){}方法。在方法中会调用一下方法:
ViewGroup中执行拦截的方法

ViewGroup中比View多了个拦截方法。onInterceptTouchEvent(MotionEvent ev);该方法是默认为false,不拦截传递到子View的触摸事件。intercepted是判断是否拦截事件。
若为true的时候ViewGroup自己处理onTouchEvent
若为true的时候。则在通过一下的方法来判断子View能否获得事件的传递:
通过View的x坐标,y坐标等来判断是否获得该事件的传递
处理完是否拦截事件的时候。

 // Dispatch to touch targets.
 if (mFirstTouchTarget == null) {
     // No touch targets so treat this as an ordinary view.
     handled = dispatchTransformedTouchEvent(ev, canceled, null,
                        TouchTarget.ALL_POINTER_IDS);
 } else {
     final boolean cancelChild = resetCancelNextUpFlag(target.child) || intercepted;
     if (dispatchTransformedTouchEvent(ev, cancelChild, target.child, target.pointerIdBits)) {
        handled = true;
        ...
     }
 }

根据ViewGroup中是否有子View来确定是否有下一级的触摸目标来执行
dispatchTransformedTouchEvent(MotionEvent event, boolean cancel, View child, int desiredPointerIdBits)方法;
那么看看这个方法中都执行了什么东西:
执行事件分发
因为ViewGroup继承与View,那么若是没有子View,那么ViewGroup自己执行View的事件分发方法,继而ViewGroup自己消化掉了onTouchEvent()事件。有子View,若是是ViewGroup那么继续执行上面的步骤,若是是View,那么执行View的事件传递执行方法。
总结以上的:
在一开始给的额布局中。我们点击view,日志输出步骤如下:
事件传递步骤
那么要是需要在父类拦截掉子类的触摸事件,重写onInterceptTouchEvent的方法,让它return true就可以了。
而若是竖直滚动事件和水平滚动事件。则可以通过复写onTouchEvent()事件,在ACTION_MOVE的时候判断手指的方向来判断是否在当前View处理触摸事件还是在上一层View处理滑动事件。

最后,从下面这篇博文中查阅到的资料受到很大的启发:
http://www.codeceo.com/article/view-event-dispatch.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值