Android 事件传递

    Android 中,控件按照树状结构排列,堆积而成。对于一个activity来说,框架预先安排了一个FrameLayout 作为 RootView。 activity 的 setContentView 方法在这个rootView中添加子View。所有的view和viewGroup 构成了一个树状结构。
    事件分发便沿着这棵树依次传递。
    
     事件传递涉及三个重要的过程:
    dispatchTouchEvent         处理分发事件的逻辑
    onInterceptTouchEvent    截取事件,决定是否要接着传递
    onTouchEvent                   处理onTouch事件逻辑。
     其中 ViewGroup 拥有上面三个过程,具备分发,拦截,处理事件的能力。而所有的View都具有onTouchEvent 和 dispatchTouchEvent 过程,具备处理和分发事件的能力。
    
     事件处理(已onTouch事件为例)的过程往往是这样的:
    我们 Touch_Down 一个最表面的view,事件从最顶层rootView开始传递。首先传递给ViewGroup-A--dispatchTouchEvent , 如果方法返回false,  事件传递到此结束 , 后续事件(例如 Touch_UP)将不再响应。如果方法返回true, 将传递至 ViewGroup-A onInterceptTouchEvent 方法。    
    在  ViewGroup-A onInterceptTouchEvent  中如果方法返回false, 表示没有被拦截,事件将传递至子控件。该方法如果返回true , 表示事件被拦截,事件将传递至 ViewGroup-A onTouchEvent 方法,处理事件。
    在  ViewGroup-A onTouchEvent 中,如果方法返回true, 表示ViewGroup 能够处理事件,后续事件(例如 Touch_UP)将也会传递至ViewGroup-A onTouchEvent 中处理。如果方法返回false , 表明事件虽然被拦截,但是处理不了,后续事件将自动丢弃。
    
    如果经过 ViewGroup - A 没有被拦截,则事件传递至子控件。如果子控件是ViewGroup - B, 则过程如上。但是注意:ViewGroup - B 如果处理了事件,ViewGroup-B onTouchEvent方法如果返回false,表明事件没有被处理,而 ViewGroup - B 有父控件,则将传递至父控件的 onTouchEvent方法,既传递至ViewGroup - A的onTouchEvent方法。
   如果经过 VIewGroup - A 没有被拦截,并且子控件是View, 则传递至子控件的 dispatchTouchEvent方法。处理过程和上一样,如果返回true,传递至 View - A 的 onTouchEvent方法,如果方法返回true, 表明View - A 能处理这类事件。后续事件都会传递至 View - A onTouchEvent. 如果方法返回false,则传递至父控件 onTouchEvent方法。

大致过程如上所述,但是文字太繁琐,写起来也很累,图示如下:

我的Demo layou层级如下:




事件将沿 着这条路前进,直到被处理,拦截,丢弃。

  

我们看几种情况:
1 :FrameLayout -- dispatchTouchEvent 返回false. 事件将结束传递,后续事件结束

2. LinearLayout 拦截事件,onTouchEvent方法返回true,表明事件可以处理, 后续事件也传递至此


                   onTouchEvent 方法返回false, 表明事件不能处理。传递至上层控件。
 



        上面几个例子只是一部分情况,但是不管情况多么复杂,道理是一样,事件自顶向下,如果不能分发(dispatchTouchEvent),结束于此。如果能够分发,传递至拦截(onInterceptTouchEvent)过程,如果被拦截则传递至事件处理的地方。没有拦截,接着传递。对ViewGroup来说,能够拦截,对于View来说,只能处理(onTouchEvent),不能拦截。如果能够处理,则事件传递至目的地,不能处理,则冒泡。

        我觉得想要弄清楚,还是得自己写的Demo 输出看下。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值