Android事件分发机制简记
来源:互联网 发布:漫画软件推荐 编辑:程序博客网 时间:2024/06/08 17:22
基础认知
当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件(Touch事件)
- Touch事件相关细节(发生触摸的位置、时间、历史记录、手势动作等)被封装成MotionEvent对象
主要发生的Touch事件有如下四种
MotionEvent.ACTION_DOWN:按下View(所有事件的开始)
MotionEvent.ACTION_MOVE:滑动View
MotionEvent.ACTION_CANCEL:非人为原因结束本次事件
MotionEvent.ACTION_UP:抬起View(与DOWN对应)
Android的UI界面是由Activity、ViewGroup、View及其派生类组合而成的
View是所有UI组件的基类
- 一般Button、ImageView、TextView等控件都是继承父类View
ViewGroup是容纳UI组件的容器,即一组View的集合(包含很多子View和子VewGroup)
其本身也是从View派生的,即ViewGroup是View的子类
是Android所有布局的父类或间接父类:项目用到的布局(LinearLayout、RelativeLayout等),都继承自ViewGroup,即属于ViewGroup子类。
与普通View的区别:ViewGroup实际上也是一个View,只不过比起View,它多了可以包含子View和定义布局参数的功能。
Android事件分发机制的本质是要解决:点击事件由哪个对象发出,经过哪些对象,最终达到哪个对象并最终得到处理。
- 这里的对象是指Activity、ViewGroup、View
Android中事件分发顺序:Activity(Window) -> ViewGroup -> View
事件分发过程由dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()三个方法协助完成
Activity的事件分发机制
当一个点击事件发生时,事件最先传到Activity的dispatchTouchEvent()进行事件分发,最终是调用了ViewGroup的dispatchTouchEvent()方法
如果ViewGroup的dispatchTouchEvent()返回true就不执行Activity的onTouchEvent()方法;如果返回false,就执行。
这样事件就从 Activity 传递到了 ViewGroup
ViewGroup事件的分发机制
Android事件分发是先传递到ViewGroup,再由ViewGroup传递到View
在ViewGroup中通过onInterceptTouchEvent()对事件传递进行拦截
onInterceptTouchEvent方法返回true代表拦截事件,即不允许事件继续向子View传递;
返回false代表不拦截事件,即允许事件继续向子View传递;(默认返回false)
子View中如果将传递的事件消费掉,ViewGroup中将无法接收到任何事件。
View事件的分发机制
onTouch()的执行高于onClick()
每当控件被点击时:
如果在回调onTouch()里返回false,就会让dispatchTouchEvent方法返回false,那么就会执行onTouchEvent();
如果回调了setOnClickListener()来给控件注册点击事件的话,最后会在performClick()方法里回调onClick()。
onTouch()返回false(该事件没被onTouch()消费掉) = dispatchTouchEvent()返回false(继续向下传递) = 执行onTouchEvent() = 执行OnClick()
如果在回调onTouch()里返回true,就会让dispatchTouchEvent方法返回true,那么将不会执行onTouchEvent(),即onClick()也不会执行;
onTouch()返回true(该事件被onTouch()消费掉) = dispatchTouchEvent()返回true(不会再继续向下传递) = 不会执行onTouchEvent() = 不会执行OnClick()
思考点
onTouch()和onTouchEvent()的区别
这两个方法都是在View的dispatchTouchEvent中调用,但onTouch优先于onTouchEvent执行。
如果在onTouch方法中返回true将事件消费掉,onTouchEvent()将不会再执行。
如果你有一个控件是非enable的,那么给它注册onTouch事件将永远得不到执行。对于这一类控件,如果我们想要监听它的touch事件,就必须通过在该控件中重写onTouchEvent方法来实现。
Touch事件的后续事件(MOVE、UP)层级传递
如果给控件注册了Touch事件,每次点击都会触发一系列action事件(ACTION_DOWN,ACTION_MOVE,ACTION_UP等)
当dispatchTouchEvent在进行事件分发的时候,只有前一个事件(如ACTION_DOWN)返回true,才会收到后一个事件(ACTION_MOVE和ACTION_UP),即如果在执行ACTION_DOWN时返回false,后面一系列的ACTION_MOVE和ACTION_UP事件都不会执行
dispatchTouchEvent()和 onTouchEvent()消费事件、终结事件传递(返回true)而onInterceptTouchEvent 并不能消费事件,它相当于是一个分叉口起到分流导流的作用,对后续的ACTION_MOVE和ACTION_UP事件接收起到非常大的作用
- 请记住:接收了ACTION_DOWN事件的函数不一定能收到后续事件(ACTION_MOVE、ACTION_UP)
如果在某个对象(Activity、ViewGroup、View)的dispatchTouchEvent()消费事件(返回true),那么收到ACTION_DOWN的函数也能收到ACTION_MOVE和ACTION_UP
如果在某个对象(Activity、ViewGroup、View)的onTouchEvent()消费事件(返回true),那么ACTION_MOVE和ACTION_UP的事件从上往下传到这个View后就不再往下传递了,而直接传给自己的onTouchEvent()并结束本次事件传递过程
- Android事件分发机制简记
- android事件分发机制
- Android事件分发机制
- Android 事件分发机制
- Android事件分发机制
- Android 事件分发机制
- Android 事件分发机制
- android 事件分发机制
- Android事件分发机制
- android 事件分发机制
- android事件分发机制
- Android 事件分发机制
- android事件分发机制
- android 事件分发机制
- android 事件分发机制
- Android 事件分发机制
- Android事件分发机制
- Android事件分发机制
- Oracle EBS 启用"帮助-诊断"
- 使用BigDecimal 将科学计数法变成普通的文本格式输出
- HDU 2602 Bone Collector
- springboot的入门学习
- 搭建cacti监控华为交换机出现的问题
- Android事件分发机制简记
- FileUtils类 使用举例
- 前段工程师photoshop---切图篇
- cocos不是内部或外部命令 解决办法
- 关于分享
- 流媒体传输协议及音视频编解码技术
- Python 3、函数式编程
- Spring 介绍
- 进口商贸易融资工具:保付加签