Android事件分发机制
零、事件分发的一些基础知识
什么是事件?
当用户触摸屏幕时,发生的点击或者触摸动作,称之为点击事件(Touch事件)。Touch事件的一些详细内容,比如触摸的位置,触摸的类型,时间的长短等被封装在一个叫做MotionEvent对象中。
事件类型
- MotionEvent.ACTION_DOWN:按下View,所有触摸或者点击事件的开始
- MotionEvent.ACTION_UP:抬起View,触摸或者点击事件的结束,与Down对应相反
- MotionEvent.ACTION_MOVE:触摸动作在屏幕上进行滑动
- MotionEvent.ACTION_CANCEL:取消事件,结束事件
因为在屏幕上,是分层的,比如是现有窗口,然后有交互界面(Activity),界面中有布局(ViewGroup),布局中有控件(View)。
那么如何确定到底该哪个控件来响应处理触摸事件呢,这就要用到事件分发机制了。一般来说,事件传递的顺序是:Activity -> ViewGroup -> View。
一、事件分发
事件的分发顺序
1个点击事件发生后,事件先传到Activity、再传到ViewGroup、最终再传到 View。
事件分发的过程
在整个事件分发,并响应事件的过程中,有三个重要的方法:
- dispatchTouchEvent:分发(传递)点击事件,当点击事件能够传递给当前View时,该方法就会被调用。
- onInterceptTouchEvent:判断是否拦截某个事件,该方法仅在ViewGroup中存在。一般情况下会在ViewGroup的dispatchTouchEvent方法中调用该方法。
- onTouchEvent:处理点击事件,在dispatchTouchEvent内部调用。
二、Activity 中的事件分发机制
Activity 中包含两个事件分发与处理的方法,分别是:
- boolean dispatchTouchEvent(MotionEvent ev):事件分发
- boolean onTouchEvent(MotionEvent event):事件消费
第一步是判断事件如果是点击事件,则调用 onUserInteraction 方法,该方法的方法体为空,可以重写这个方法,用于处理一些交互问题。
第二步是调用了 Window 的 superDispatchTouchEvent 方法,如果返回 true,则表示此事件已被消费,结束此次分发流程,false 则继续调用该 Activity 的 onTouchEvent 方法处理该事件。
总结一下,事件进入 Activity的dispatchTouchEvent 开始分发,首先会将该事件传递给该页面的 ViewGroup,ViewGroup 如果消费了该事件,则分发结束,未消费则继续调用 Activity#onTouchEvent 方法处理事件,流程如图:
三、ViewGroup 中的事件分发
ViewGroup 中包含三个事件分发相关的方法:
- dispatchTouchEvent(MotionEvent ev):
- onIntercepTouchEvent(MotionEvent ev):
- onTouchEvent(MotionEvent ev):
1、事件首先会进入 dispatchTouchEvent 方法开始分发。
2、dispatchTouchEvent方法通过调用onInterceptTouchEvent 方法判断是否需要拦截事件。
- 2.1、如果需要拦截(方法返回 true),则表示当前 ViewGroup 希望处理该事件,或者不希望子 View 处理该事件,此时将直接调用 onTouchEvent 方法。
- 2.2、如果不需要拦截,则将该事件传递给子 View 的 onTouchEvent 方法,或者子 ViewGroup 的 dispatchTouchEvent 方法。
3、onTouchEvent 方法, 该方法用于消费事件,返回值表示是否已消费,在两种情况下会被调用:onInterceptTouchEvent 方法确认需要拦截该事件以及子 View/ViewGroup 未消费该事件。
- 3.1、如果该方法返回 true,则表示事件已消费,此次事件分发就成结束;
- 3.2、如果返回 false,则表示未消费该事件,会继续调用父 ViewGroup 或 Activity 的 onTouchEvent 方法。
ViewGroup的事件分发机制如下:
四、View 中的事件分发机制
View 中包含如下两个用于处理事件分发相关的方法:
- dispatchTouchEvent(MotionEvent event)
- onTouchEvent(MotionEvent event)
ViewGroup 会将事件传递给 dispatchTouchEvent 方法,由于不是 ViewGroup,不需要考虑向下传递事件的逻辑,所以 View 中的事件处理流程很简单。
五、事件分发总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix