关于android中事件传递和分发的一些小理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于android中事件传递和分发的一些小理解相关的知识,希望对你有一定的参考价值。

 android中 当我们的手指触摸屏幕将产生一个事件,

 (假设 这个过程中如果没有显示的去拦截该事件的话)
   这个事件会逐级传递到视图的最底层,即使在中间某些视图会响应这个事件( 这个视图也不会去消费这个事件),
  
   仍然是会传递到底层(底层不响应该事件),然后再由底层回传到顶层,在传回顶层的过程中 ,
   原先会响应该事件的视图才会去消费这个事件

   例如在左图中                                 A
                                                     B(会响应该事件)
                                                     C
                                                     D

 (假设在这整个过程中 没有做任何特殊的处理)

   事件从A开始向D传递,这个时候B不会消费这个事件
   只有当事件从D回传到A的过程中 B才回去消费这个事件。


   但是,假设D也会响应这个事件 ,那么该事件将会被D所消费 这个时候事件停止传递 那么B也就没有机会再去消费该事件了。

   也就是说这个时候的B就相当于无视了这个触摸(点击)事件。


   那为什么传到底层D时事件就会被消费呢? (假设底层D会响应该事件)


   因为,VIewGroup才有 onInterceptTouchEvent()方法 ,而view中是没有的 ,也就是说
   当view响应事件时 就一定会去消费该事件,因为它别无选择 只能消费掉该事件
   而ViewGroup则默认是不拦截事件 而是分发给子View的.

 下面是关于拦截与分发的三个方法:

  dispatchTouchEvent()方法用于事件的分发,Android中所有的事件都必须经过这个方法的 分发,
  然后决定是自身消费当前事件还是继续往下分发给子控件处理。返回true表示不继续分发,
  事件没有被消费。返回false则继续往下分发,
  如果是 ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件。

  onInterceptTouchEvent()是ViewGroup中才有的方法,View中没有, ( 即ViewGroup中的拦截的方法)
  它的作用是 负责事件的拦截,返回true的时候表示拦截当前事件,
  不继续往下分发,交给自身的onTouchEvent进行处理(即会触发onTouchEvent()方法)。返回false则不拦截,
  继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的。
 
  onTouchEvent()方法用于事件的处理,返回true表示消费处理当前事件,
  返回false则不处理,交给子控件进行继续分发。

 

 补充与总结: 一个事件的传递包含正向传递(父view传给子view的过程)和回传传递(子view传给父view的过程)
  在正向传递中 父view可以拦截事件,使该事件不传递给子view ;相同的,在回传传递中,子view也可以反拦截事件,使之不再回传给父view

   //在X轴和Y轴滑动的距离
                float DX = Math.abs(endX-downX);
                float DY = Math.abs(endY-downY);
                if(DX > DY&&DX>8){
                    //水平方向滑动
                    //响应侧滑
                    //反拦截-事件给SlideLayout
                    getParent().requestDisallowInterceptTouchEvent(true); (实际上是父view调用了反拦截的方法)
                }

 

对于各种事件的传递和分发的冲突的问题 重点是要分析好各个视图之间的从属关系
    然后1.判断(反)拦截与否,2.判断水平滑动是否大于竖直滑动

    核心思想是 : 让不同的操作做好自己的事件 不要干扰到其他人的事情

    例如侧滑菜单中 视图的关系假设是这样的
    activity ——》relatilayout--》listview——》slidelayout(自定义viewGroup)——》1.content(textview)
                                                                                                              ——》 2.menu(textview)

侧滑菜单 (1.处理侧滑时与listView下滑的冲突 解决:反拦截事件 (实际上是slidelayout与slidelayout之间的冲突
             也就是下滑的这个事件slidelayout不响应而listview响应)
          2.处理listView条目点击事件与侧滑时的冲突(通过分析从属关系得知,实际上是content与slidelayout之间的冲突
             也就是content把事件消费了,slidelayout得不到事件从而无法滑动了) 解决:拦截事件)

 

 

 

以示只是我一家之言,如有错误,请指正。

 

 

 

 

                                                          -----爱生活,爱android.

 






































以上是关于关于android中事件传递和分发的一些小理解的主要内容,如果未能解决你的问题,请参考以下文章

Android源码分析:View的事件分发机制探析

Android事件分发机制完全解析,带你从源码的角度彻底理解(上)

Android事件分发机制完全解析,带你从源码的角度彻底理解

(转) Android事件分发机制完全解析,带你从源码的角度彻底理解(上)

Android事件分发机制详解:史上最全面最易懂

Android事件分发机制详解