android 个人对事件传递的总结

原创 2015年11月19日 09:10:21

关键的三个方法

  • dispatchTouchEvent:事件的分发工作,返回值代表事件是否被消耗
  • onInterceptTouchEvent:ViewGroup用于拦截事件的方法
  • onTouchEvent:事件处理的方法

阅读前的关键字说明

  • 后续事件:即down事件后的move跟up事件。
  • touch处理:即是先调用setOnTouchListener的listener,如果返回了false,则代表事件没有被消耗,会继续调用onTouchEvent进行处理。两个方法的返回值都代表事件是否被消耗的意思,一但消费了,事件不会继续传递

通俗的讲事件传递的思路
最顶层控件会轮流传给子控件询问是否消耗了事件,当某个子控件消耗了事件,则后续的事件(move、up)会继续传递给该控件处理。当然,传递过程中还是会继续经过父控件再到当前控件,也会继续调用父控件的onInterceptTouchEvent来询问父控件本身要不要拦截。(但不会传递给别的子控件)

事件传递的代码
是写在super.dispatchTouchEvent方法中,所以一般不能删掉这行代码

怎样确定事件被消耗
事件是否被消耗的真正代表方法是dispatchTouchEvent的返回值,返回true代表被消耗,返回false代表没被消耗。

事件传递的逻辑
事件传递的方法是dispatchTouchEvent,其实他的主要作用是询问子控件是否需要消耗掉事件,如果子控件是ViewGroup,则又会去调用他的子控件的dispatchTouchEvent来询问,而这询问是有一个规律的,就成了一个事件传递的过程。最外层是Activity来调用顶层ViewGroup的dispatchTouchEvent,然后ViewGroup也会去调用子控件的dispatchTouchEvent。方法的返回结果代表事件是否被消耗。该方法ViewGroup跟View都有,且处理方式不同。

  • ViewGroup:会先询问自己是否需要拦截事件。
    • 如果需要,则该ViewGroup不会再传递给自己的子控件,而是调用自己的touch来处理。(可能想像为该ViewGroup已经变成了一个View)
      • 如果touch返回了true,则正常,说明事件在自己这里被消费了,dispatchTouchEvent也会返回true来告诉当前ViewGroupr的父控件不用再往别的控件中传递,事件说明被自身拦截,后续事件也会继续传递到此处。
      • 如果touch返回了false,则dispatchTouchEvent也会返回false,来告诉自己的父控件事件没有被消耗,而父控件会接着传递给另一个子控件进行处理
    • 如果不需要,则会调用子控件的dispatchTouchEvent
  • VIew:会直接进行touch处理,然后touch处理的返回值就是自身dispatchTouchEvent的返回值

事件丢失
当在down事件的时候,传递到的控件当中没有一个dispatchTouchEvent返回true,则事件会丢失,之后的move及up事件,代码都不会响应,需要重新触发down事件(重新按下)

有关ViewGroup的拦截事件
拦截事件就是指让自己来touch处理,其实可以更加明了的讲,就是ViewGroup拦截事件后,就变成了一个View一样。

父控件中有两个子控件的注意事项
假设父控件有两子控件A、B,首先问了A,A控件dispatchTouchEvent返回false,代表A没有消耗事件,然后就会传递给B,而B如果消耗了的话,后续的事件就是直接先传递给父控件,再传给B,而不会再经过A。

请求ViewGroup不要拦截事件:ViewGroup有个方法叫做requestDisallowInterceptTouchEvent(boolean b)来使自身不要拦截事件,设置true则表示不要拦截,设置false则恢复正常。下面有具体的应用场景

各控件的事件传递思路与控件间的事件处理

  • Button:Button默认是会把事件消耗掉的(onTouchEvent返回true,之后dispatchTouchEvent也会返回true)
  • ListView内有一个Button:ListView是一个ViewGroup,他拦截事件的前提是在down后,进行了一定数值的上移或下移时,就会将事件抢过来自己处理(上拉下拉的效果就是处理的结果)而如果ListView的item内有一个Button,事件传递的思路是这样的:首先按下Button的时候,事件是给Button抢了过来,之后的后续事件如果是上移或下移了,事件会突然被ListVIew抢走(因为后续事件会经过ListView,且会询问ListView是否拦截,而ListView是在onInterceptTouchEvent中获取到事件的相关信息来判断是否上移下移来决定拦不拦截)
  • ScrollView内有一个ListView(假设ListVIew只占了ScrollView的一部份位置):首先事件肯定是先给了ScrollView,然后ScrollView内部再传递给ListView,而ScrollView跟ListView的拦截事件的判断都是一样的(判断是否进行了上拉或下拉,是则进行拦截)所以在进行上下滚动后,ListView是绝对拿不到事件的,但down事件是肯定会拿到。所以解决方法是在ListView中的onInterceptTouchEvent当中的down事件发生的时候,调用 ScrollView对象. requestDisallowInterceptTouchEvent(true),来让ScrollView不要抢事件,之后在up事件时,再调用 ScrollView对象. requestDisallowInterceptTouchEvent(false) 来让ScrollView恢复正常。这样做的话,就是表明当按下的地方是ListView时,上下滑动时是ListView滑动,按下时是在ScrollView内的其他地方,则是ScrollView的上下滑动。

Android 自定义控件onTouch事件浅析和个人总结

本文主要参考博客:http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html   http://blog.csdn.net/guolin_...
  • maxliyu
  • maxliyu
  • 2016年04月19日 22:29
  • 889

MotionEvent事件传递个人总结

在开发过程中,对于复杂的布局,经常需要手动处理MotionEvent的传递和处理。 一、基础知识 总的来说,处理消息的函数有三个: dispatchTouchEvent():负责消息的传递,原理应...

javascript中对各种事件处理程序的个人总结

这些天对在js的整理学习中,发现了一个我以前不知道的js事件处理方式,相信很多同学在起初学习web开发的时候,可能会直接将onclick之类的属性直接赋值放到html标签内,这样会使页面代码显得复杂混...

【图形化编程软件】 sikuli常用函数、简单事件操作 键盘操作 个人总结笔记

sikuli函数、简单事件操作个人总结笔记   作者:stormwy 网址:http://blog.csdn.net/stormwy/article/details/7955137 ...
  • stormwy
  • stormwy
  • 2012年09月07日 14:48
  • 21310

sikuli函数、简单事件操作个人总结笔记

sikuli函数、简单事件操作个人总结笔记   作者:stormwy 网址:http://blog.csdn.net/stormwy/article/details/7955137 ...
  • airfer
  • airfer
  • 2015年08月17日 16:27
  • 2946

【Sikuli】 sikuli常用函数、简单事件操作 键盘操作 个人总结笔记

sikuli函数、简单事件操作个人总结笔记   作者:stormwy 网址:http://blog.csdn.net/stormwy/article/details/7955137 其...

C#中的委托与事件详解<个人总结>

委托的三种定义方法 new(典型方法) 匿名类 lamda表达式 事实上,这些方法 using System; using System.Collections.Generic; using Sys...

关于asp.net中控件&控件事件的个人总结

●ASP。NET中共有几种类型的控件? 三种:1-asp.net控件(动态) 2-标准的html控件(静态) 3-标准的html控件加runat="server"属性(动态) 动态页面主要由这三种...

【图形化编程软件】 sikuli常用函数、简单事件操作 键盘操作 个人总结笔记

sikuli函数、简单事件操作个人总结笔记   作者:stormwy 网址:http://blog.csdn.net/stormwy/article/details/7955137 ...

Android onTouch事件传递机制

  • 2017年02月28日 17:05
  • 27.68MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android 个人对事件传递的总结
举报原因:
原因补充:

(最多只允许输入30个字)