zoukankan      html  css  js  c++  java
  • 关于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得不到事件从而无法滑动了) 解决:拦截事件)

  • 相关阅读:
    10 个深恶痛绝的 Java 异常。。
    为什么公司宁愿 25K 重新招人,也不给你加到 20K?原因太现实……
    推荐一款代码神器,代码量至少省一半!
    Spring Cloud Greenwich 正式发布,Hystrix 即将寿终正寝。。
    hdu 3853 LOOPS(概率 dp 期望)
    hdu 5245 Joyful(期望的计算,好题)
    hdu 4336 Card Collector(期望 dp 状态压缩)
    hdu 4405 Aeroplane chess(概率+dp)
    hdu 5036 Explosion(概率期望+bitset)
    hdu 5033 Building (单调栈 或 暴力枚举 )
  • 原文地址:https://www.cnblogs.com/chengxuxia/p/6648617.html
Copyright © 2011-2022 走看看