博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于android中事件传递和分发的一些小理解
阅读量:5967 次
发布时间:2019-06-19

本文共 1879 字,大约阅读时间需要 6 分钟。

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

 

转载于:https://www.cnblogs.com/chengxuxia/p/6648617.html

你可能感兴趣的文章
Nsrp实现juniper防火墙的高可用性【HA】!
查看>>
Android 动态移动控件实现
查看>>
oracle11g 安装在rhel5.0笔记
查看>>
解决Lync 2013演示PPT提示证书问题的多种方法
查看>>
[转]经典正则表达式
查看>>
JDBC+Servlet+JSP整合开发之26.JSP内建对象
查看>>
【下载】深入oracle数据库专用虚拟机环境部署方案《VirtualBox+OELR5U7x86_64+Oracle11gR2》...
查看>>
值得推荐的C/C++开源框架和库
查看>>
列式存储
查看>>
Linux下eclipse编译C/C++程序遇到 undefined reference to `pthread_create'的异常解决办法
查看>>
ajax上传图片的本质
查看>>
转]最长递增子序列问题的求解
查看>>
SilverLight:基础控件使用(6)-Slider控件
查看>>
Android写的一个设置图片查看器,可以调整透明度
查看>>
第 5 章 File Share
查看>>
判断字符串解析是JsonObject或者JsonArray
查看>>
[LeetCode] Implement strStr()
查看>>
多模块Struts应用程序的几个问题(及部分解决方法)
查看>>
1.2. MariaDB
查看>>
SpringSide示例之HelloWorld
查看>>