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得不到事件从而无法滑动了) 解决:拦截事件)

  • 相关阅读:
    c-free5
    node.js模块
    cd
    bower
    atom插件
    反射(操作MetaData)
    1.Html
    SQL语句 把一个表的数据复制到另外一个表里面
    Redis 可视化工具
    C# 多文件压缩包
  • 原文地址:https://www.cnblogs.com/chengxuxia/p/6648617.html
Copyright © 2011-2022 走看看