Android事件分发的流程
大致来讲Android的事件分发机制是从Android 的 Touch事件发生 到处理的一系列流程,当用户操作触摸屏幕
时,发生的一系列事件,被封装为MotionEvent对象 MotionEvent事件类型为:
MotionEvent.Action_DOWN ——> 按下View(所有事件的开始)
MotionEvent.Action_UP ——> 抬起View
MotionEvent.Action_MOVE ——> 滑动View
MotionEvent.Action_CANCEL ——>结束事件(非人为原因)
事件的传递顺序
Activity ——> ViewGroup ——>View
Window DecorView 与 Activity 的关系
如图所示,activity下是PhoneWindow (Window的唯一实现类)而 DecorView是PhoneWindow的
内部类。
其实所有的View的展示都是由Window来进行实现的,在我们调用setContentView()时,其实是调用的
PhoneWindow的setContentView()方法,在其setContentView()中,会初始化一个DecorView,
DecorView会产生一个mContentParent,这个mContentParent就是我们要加载显示的东西,
后会调用inflate()来进行对布局文件的加载
简单理解为Activity是一个工人,它来控制Window;Window是一面显示屏,用来显示信息;
View就是要显示在显示屏上的信息,这些View都是层层重叠在一起
(通过infalte()和addView())放到Window显示屏上的。
其通过这种 “外包” 的方式使得自己不用关心 View 操作的细节,做到降低耦合。
Activity消息分发机制
事件分发开始 ——>
Activity.dispatchTouchEvent() ——>
getWindow().superDispatchEvent()(到这里开始调用PhoneWindow分发)
——>mDecor.superDispatchTouchEvent() (到这里开始调用DecorView来进行事件分发)
(由于DecorView是继承自FrameLayout,而FrameLayout是ViewGroup的子类,所以下面进行的是
ViewGroup的事件分发)即ViewGroup.dispatchTouchEvent(),实现了事件从ViewGroup到View传递.
——>如果返回true ——>Activity.dispatchTouchEvent()返回true ——>事件分发结束
——>如果返回false(即子view没有消耗掉事件) ——>调用Activity.onTouchEvent()消耗事件
ViewGroup的事件分发机制:
当activity调用mDecor.superDispatchTouchEvent()方法时,事件就传递给ViewGroup来进行分发。
开始 ——> ViewGroup.dispatchTouchEvent() ——>ViewGroup.onInterceptTouchEvent()
(拦截事件) ——> 如果拦截 ——> super.disoatchTouchEvent()(即 View.dispatchTouchEvent())
——> 自己处理事件 onTouch() ——>onTouchEvent()——>onClick()
(不拦截事件)——>for循环遍历子View确定当前按下的哪个view ——>调用View的dispatchTouchEvent()
从而实现事件从ViewGroup到View的传递
View的事件分发机制
开始 ——>View.dispatchTouchEvent() ——>View.onTouch()(如果设置了onTouch事件与监听器)
onTouch()的返回值(手动重写设置)
——>true(事件被消费,不再继续往下传递) ——>disTouchEvent()返回true
——>false(事件没有被消费,继续往下传递) ——>onTouchEvent() ——>onClick();