View的事件传递机制-实例分析(2)

来源:互联网 发布:python 宝典 高清 pdf 编辑:程序博客网 时间:2024/06/08 16:42

        上一篇view的事件传递机制介绍的文章中,介绍了view的事件机制相关原理,主要围绕与 Touch 事件相关方法:dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev)展开分析,这里就围绕这几个方法进行实例分析,实例截图如下:

    


    上面的布局大致是这样子的,外层、中间层、内层都是线性布局,都是继承于LinearLayout实现的,在子类中都实现了dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev)三个方法的重载,并打印相关的Log供分析使用。为简单起见,下面就针对每一种情况单独分析(也就是说上面的三个函数只会有一个返回true、false,其它采用默认值进行分析)。

    (0)全部是默认值,结果此时点击最内层,结果如下:


     此时由于点击的是内层,且没有事件的拦截,在进行事件分发与拦截时能够一直传递到target view(我们点击的view),所以事件能够一直传递到最内层的View TouchEventSecondChilds(向下拦截过程中事件没有被拦截),然后由该View开始向上冒泡处理(向上冒泡过程),由于这个过程也没有谁对事件有兴趣(在onTouchEvent中返回true表示对当前事件有兴趣),所以down事件后续的事件都没有传递到相应的View中,而是直接在Activity中被消费掉了。

    (1)在中间层的dispatchTouchEvent返回true,其它采用默认值,点击中间区域,结果如下:


      此时我点击的是中间区域的位置,且点击的速度比较快,从Log中我们可以发现并没有发生Move事件;事件从Activity传递到target view也就是TouchEventChilds,由于在target view中的dispatchTouchEvent返回true,所以此时事件会被拦截,从Log中我们发现事件被拦截且由当前view(dispatchTouchEvent)及外层view(dispatchTouchEvent及onInterceptTouchEvent )消费。

    (2)在中间层的dispatchTouchEvent返回false,其它采用默认值,点击中间区域,结果如下:


    同样返回false时,事件也还是会被拦截,只不过与返回true时有所不同而已,此时target view会把事件返回给它的父view,由父view的onTouchEvent函数进行冒泡处理,正如上面的结果所示。

    (3)在中间层的dispatchTouchEvent返回return super.dispatchTouchEvent(ev),点击最内层,其它采用默认值,结果如下:


    如果所示,此时down事件传递到了最内层TouchEventSecondChilds,也就是说此时事件会一路传递下去,直到有谁拦截或者有谁对它感兴趣为止,否则就到target view时才进行冒泡处理。

    (4)在中间层的onInterceptTouchEvent返回true,其它采用默认值,点击中间区域结果如下:


    由Log可以看出,中间层拦截了down事件,之后从它开始冒泡处理,后面的事件都没有传递到中间层,但是如果中间层的onInterceptTouchEvent返回true的同时,也在中间层的onTouchEvent返回true,则此时情况会有所不同,如下图所示:


    由于此时onInterceptTouchEvent返回true,所以会拦截当前事件,而我们又在相同view的onTouchEvent返回true,表示对此down事件感兴趣,所以会把事件的处理交给当前target view,由上面的标记1可知,会在onInterceptTouchEvent中返回true,此时会拦截down事件,由后面的标记2处可知,后续的事件已经传递到了当前target view。

    (5)在中间层的onInterceptTouchEvent返回false,其它采用默认值,点击最内层区域结果如下:


     由于onInterceptTouchEvent 返回 false,则表示将事件放行(传递到子view的dispatchTouchEvent进行事件分发),当前 View 上的事件会被传递到子 View 上,再由子 View 的 dispatchTouchEvent 来开始这个事件的分发;由上面的Log我们也可以看出事件已经传递到了最内层区域,事件被放行,其实此时与返回默认值(super.onInterceptTouchEvent(ev))的行为一致。

   上面是自己根据实例结果得出来的一些分析结果,若有不证,还欢迎指正,感觉来访,结果附上测试程序。

源代码

0 0
原创粉丝点击