《Android开发艺术探索》3.4.2 事件分发的源码解析(顶级View对点击事件的分发过程)

1、Activity对点击事件的分发过程

点击事件由MotionEvent表示,由Activity的dispatchTouchEvent进行shij事件派发,

具体的工作步骤:

Activity内部的Window(实现类PhoneWindow)->DecorView->到达顶级View(根View)

2、顶级View对点击事件的分发过程

具体逻辑:如果顶级ViewGroup拦截事件即onInterceptTouchEvent返回true,则事件由ViewGroup处理,这时如果ViewGroup的mOnTouchListener被设置,则onTouch会被调用,否则onTouchEvent会被调用。也就是说,如果都提供的话,onTouch会屏蔽掉onTouchEvent。在onTouchEvent中,如果设置了mOnClickListener,则onClick会被调用。如果顶级ViewGroup不拦截事件,事件会传递给它所在的点击事件链上的子View,这是子View的dispatchTouchEvent会被调用。到此为止,事件已经从ding顶级View传递给下一层View,接下来的传递过程和顶级View是一致的,如此循环,完成整个事件的分发。(摘自《Android开发艺术探索》P146)

(1)ViewGroup对点击事件的分发过程,主要实现在ViewGroup的dispatchTouchEvent方法中,具体源码及我的理解

//Check for interception.
final boolean intercepted;
if(actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null){
    fianl boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
    if(!disallowIntercept){
        intercepted = onInterceptTouchEvent(ev);
        ev.setAvtion(action);//restore action in case it was changed
    }else{
        intercepted = false;//不拦截,向下传递
    }
}else{
    intercepted = true;//拦截(不是DOWN操作,没有子View)
}

代码分段理解:

if(actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null){

mFirstTouchTarget != null:当ViewGroup不拦截事件并将事件交由子View处理时,此等式成立。

1)无论是否有DOWN操作,只要有子View;2)包含DOWN操作,无论是否有子View;3)包含DOWN操作,并且含有子View;是以上三种情况之一就进入for循环,否则直接拦截

fianl boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;

若mGroupFlags中设置了FLAG_DISALLOW_INTERCEPT,此处disallowIntercept为true

if(!disallowIntercept){
        intercepted = onInterceptTouchEvent(ev);
        ev.setAvtion(action);//restore action in case it was changed

进入上述循环的操作原因是:包含DOWN操作,在DOWN操作中会重置FLAG_DISALLOW_INTERCEPT标记位,使得disallowIntercept为false。循环内部:调用onInterceptTouchEvent(ev);判断是否拦截。

else{
        intercepted = false;//不拦截,向下传递
    }

没进入for内部原因:在子View中设置了FLAG_DISALLOW_INTERCEPT标记位,disallowIntercept为true,进入else,不拦截。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值