android 个人对事件传递的总结
来源:互联网 发布:淳化阁帖 知乎 编辑:程序博客网 时间:2024/05/18 03:22
关键的三个方法:
- 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
- 如果需要,则该ViewGroup不会再传递给自己的子控件,而是调用自己的touch来处理。(可能想像为该ViewGroup已经变成了一个View)
- 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 个人对事件传递的总结
- Android 事件的传递总结
- MotionEvent事件传递个人总结
- Android触屏事件传递(个人实践总结)
- 有诚意的个人onTouchEvent事件传递机制总结(多图!) ...
- android事件传递总结
- Android 事件传递总结
- Android Touch事件传递的一些总结
- Android中事件传递机制的总结
- Android中事件传递机制的总结
- Android中事件传递机制的总结
- Android中事件传递机制的总结
- Android中事件传递机制的总结
- javascript中对各种事件处理程序的个人总结
- 个人对Android Touch事件机制的理解
- Android Touch事件传递总结
- android view事件传递总结
- android 事件的传递
- Linux下以文件方式手动修改虚拟机ip地址(慕课网笔记)
- case based machine learning
- 消息机制Too many arguments to function call错误
- 短信发送器
- SQLNET.INBOUND_CONNECT_TIMEOUT
- android 个人对事件传递的总结
- jQuery学习实例:图片提示效果
- Myeclipse10注册码
- MyEclipse 8.5 注册--取消MyEclipse Trial Expired解决办法
- Flex 术语尚未定义,并且无任何属性 gc.refresh();
- Firefox源码试读之一: 何处决定新链接或书签是新标签页还是新窗口,当前窗口打开
- 解决oracle 11G exp 不能导出空表问题
- 123
- Java正则表达式