Android事件分发
来源:互联网 发布:h3c配置vlan多个端口 编辑:程序博客网 时间:2024/06/01 09:38
Android事件分发,其实就是从RootView开始,以树形结构逐层向子View分发事件,直到某个View表示需要处理该事件,其父View则将其记录下来,之后的事件都传递到该View,若子View不需要此事件,则返回给它的父 View进行处理,而在分发的过程中,父 View可以主动选择是否拦截该事件直接自己处理。
涉及的方法主要有:
1.dispatchTouchEvent(MotionEvent ev) 事件分发
2.onInterceptTouchEvent(MotionEvent ev) 事件拦截
3.onTouchEvent(MotionEvent ev) 事件处理
因为Activity的事件分发实质上也是通过其内部的ViewGroup进行分发的,所以讨论得对象只需要分为View与ViewGroup。
一.对于View
在Android的整个View体系中,View(此处的View指的具体某一个控件)的角色就像是树的叶子,所以没有事件分发,没有事件拦截,需要考虑的就是是否消费这个事件。
View的dispatchTouchEvent 实际上返回的就是onTouchEvent(event),可以理解为它本身没有子View,所谓的分发也就是分发给自己,至于是否要处理这个事件(只限于Acition_Down事件),则是由onTouchEvent(event)的返回值来决定。若onTouchEvent(event)返回true,则消费这个事件,便表示它是真正要处理这次请求的View,之后的事件(Move,Up)都回由该View来处理,若返回的false,则说明该View不处理该事件,将由其父View决定是否处理该事件。
对于View 来说,更应该关注的是onTouchEvent(event) onTouchListener.onTouch() 以及OnClickListener.onClick等设置回调监听方法的顺序。
二.对于ViewGroup
这里的ViewGroup只考虑有子View的情况,没有子View的ViewGroup可以当作View来处理。有子View的存在,要考虑到事件的分发dispatchTouchEvent,事件拦截onInterceptTouchEvent以及事件处理onTouchEvent。
dispatchTouchEvent :只负责事件的分发,当返回值是true的时候则会停止事件的分发,若返回fasle则由其父View的onTouchEvent处理该事件,若返回super.dispatchTouchEvent则会分发给onInterceptTouchEvent.
onInterceptTouchEvent:决定当前的ViewGroup是否拦截该事件,若返回true则将事件交给onTouchEvent处理,若返回false则将事件继续分发给子View。
onTouchEvent:与View相同,根据返回值决定是否消费该事件 .
常见的事件冲突:
问题一:ListView 添加ViewPager 作为header
解决思路:重写ViewPager,根据水平滑动距离与竖直滑动距离来判断滑动意图,若是水平滑动,则通过getParent().requestDisallowInterceptTouchEvent(true)让父控件不拦截ViewPager的事件,反之通过getParent().requestDisallowInterceptTouchEvent(false)让父控件处理该事件。
问题二:ScrollView嵌套ViewPager
解决思路:
1.重写ViewPager,与问题一相同
2.重写ScrollView,在onInterceptTouchEvent()中通过判断x与y方向的值来决定返回值
问题三:ViewPager嵌套ViewPager
解决思路:此场景也就是外部ViewPager可滑动,而内嵌的ViewPager无法滑动,解决方法可通过重写内嵌的ViewPager,利用requestDisallowInterceptTouchEvent来请求父控件不要屏蔽事件,可判断首末页将事件交给父控件处理,进行优化。
总结:此类问题的根本就是考虑应该将事件给谁进行处理,根据事件分发的机制,总是由父控件向子控件分发,因此也可以说解决的思路在于考虑父控件是否应该拦截该事件,从源码来看,父控件是否拦截事件由disallowIntercept(通过此方法设置requestDisallowInterceptTouchEvent())与onInterceptTouchEvent()的返回值来确定,所以一般解决此类型的事件冲突根据手势方向和触摸点坐标来判断,实际的操作就是重写子view或者父view。
- android事件分发
- android 事件分发
- android事件分发
- android事件分发机制
- Android 事件分发
- Android事件分发机制
- Android 事件分发机制
- Android事件分发机制
- android事件分发
- Android事件的分发
- Android 事件分发机制
- android事件的分发
- Android 事件分发机制
- android 事件分发机制
- Android事件分发机制
- android 事件分发机制
- android事件分发机制
- Android 事件分发
- 【Lintcode】斐波纳契数列
- sscanf,sscanf_s及其相关用法
- codeforce 621 B. Wet Shark and Bishops
- 算法系列_基础01_O(nlogn)的理解
- 自定义控制器的转场动画(Push、Pop)
- Android事件分发
- Android学习笔记(31):滚动视图ScrollView
- Cookie/Session机制详解
- 欢迎使用CSDN-markdown编辑器
- HTTPS 初解
- Json:前台对象数组传到后台解析
- 工具
- 详细解释强力的图片加载框架 Glide的配置(顺便补充下CollapsingToolbarLayout的一些功能)
- 名字与地址转换