activity事件分发流程
view的事件分发流程
Activity 事件分发
Activity 负责生命周期和处理事件。
Window负责视图的控制。
一个Activity包含了一个Window, 一个Window才真正代表了一个窗口。
Window包含了一个顶级的View -> DecorView
Activity中setContentView的视图就是DecorView的子元素。
所有的事件都要经过DecorView才会传递给我们的View。
传递层级:Activity->Window->DecorView->ViewGroup->View
事件传递的三个主要对象:Activity、ViewGroup、View
事件序列:从手指按下屏幕开始,到手指离开屏幕所产生的一系列事件。
传递层级:Activity->Window->DecorView->ViewGroup->View
View 事件传递
熟记流程图、翻看源码
事件默认传递流程和在同一事件序列中的变化
分别创建了MyActivity extends Activity,MyViewGroup extends FrameLayout,MyView extends View
然后分别重写他们需要的方法dispatchTouchEvent、onTouchEvent,特别的是在ViewGroup中多重写一个onInterceptTouchEvent
根据流程图,可以发现
传递顺序Activity-ViewGroup-View
由上自下的dispatvhTouchEventh互相传递后,到由下而上的onTouchEvent互相传递
以上进入分发的过程。判断是否符合安全策略。符合安全策略-继续,是鼠标-结束不分发,
注册了touchListener方法,里面的onTouch方法返回true标志着事件被消费了。
如果不是取消事件并且没有被分发,继续分发处理。
当前动作是按下、移动时,首先清空之前所有的触摸点信息。然后获取到可以接收的子view的集合
从前到后遍历子view,尝试找到真正点击的view。
用户没有定义了view的绘制顺序,返回当前下标。
定义了的话,通过getChildDrawingOrder获取View的下标,需要重写这个方法。
所以一般返回i。
在view列表中拿出view,否则在children中拿出。
*** 看库或框架的源码时,需要的是捋清楚代码的思路,理解核心思想,而不是明白其中每一行代码的实现。
接下来判断onInterceptTouchEvent方法的值
发现一般情况下这个方法都会返回false,因为点击来源!=鼠标等等。
第一个判断:这个值在View中可以找到,是个检测用的对象
第二个判断:提供的辅助功能的选项,帮助有障碍的用户的使用,不影响方法调用
接下来正式进入事件分发的逻辑代码中
判断安全策略,
* dispatchTouchEvent 标志着事件进入到了ViewGroup里面。首先被调用到。
* onInterceptTouchEvent 在过程中被调用。true=当前ViewGroup消费掉。false=传递下去。
* onTouchEvent ViewGroup没有onTouchEvent方法的实现,他是在View中实现的。
应用场景:希望事件进行到ViewGroup终止,不传输到子View中,用户的触摸事件自行处理。
处理:重写onInterceptTouchEvent并返回true,同时重写onTouchEvent方法,在其中编写事件处理逻辑即可。
事件未被消费,当前视图都没能处理掉这个事件,才会去调用Activity的onTouchEvent方法,且他的返回值作为dispathchEvent的返回值。
查看Activity中onTouchEvent方法的实现逻辑,发现其中一个的判断逻辑很重要,如果返回为true则会关闭当前界面且返回true。
查看Window中shouldCloseOnTouch方法,当这三个bolean值均为true时返回true。
* mCloseOnTouchOutside=true这个值表示当前Activity支持点击空白区域让acitvity消失。这个变量一般在downLoad的时候这个值才为true。
* peekDecorView的实现在PhoneWindow,返回的是当前的dectorView。
* isOutside =true 表示当前触摸的点击事件是在顶层View DoctorView之外的,没有点击到DoctorView里面。
Activity整体传递流程比较线性,如果还是不清楚可以再回看源码及流程图消化吸收。
查看源码,dispatchTouchEvent方法时发现:
1、当action是按下的时候(也就是当事件刚开始的时候)会调用onUserInteraction方法,而内部并无具体实现——所以在事件刚开始时可以实现这个方法用于监听事件开始。
2、当获取上层view的superDispatchTouchEvent方法返回是true的时候就消费掉这个事件,否则就传给onTouchEvent处理。(符合上一节说的流程)
3、 Activity+Window+DecorView之间的关系:每个Activity都持有一个window对象,window本身是一个抽象类,有一个唯一的实现PhoneWindow,PhoneWindow持有了一个DecorView的实例,DecorView是Activity最顶层的View,他继承自FrameLayout。
4、FrameLayout继承自ViewGroup,FrameLayout要实现的superDispatchTouchEvent方法在VIewGroup中实现了。
Activity中涉及到了两个方法,返回值均为true/false,根据父类dispathTouchEvent的返回走哪个方法。
dispatchTouchEvent返回true,事件被消费,事件结束。
onTouchEvent无论返回true/false,事件都结束。
事件产生的时候会有这些类型,可以想象下手指在屏幕中的活动
按下-移动-抬起,存在这样一个固定的规律,移动可以不存在
安卓中存在的这样一个基本的层级关系和传递层级
事件分发的定义和由来,及他的出现的机制的统筹定义
事件分发流程
事件在Activity的分发
系统把事件封装为MotionEvent对象,事件分发的过程就是MotionEvent分发的过程。
事件序列:从手指按下屏幕开始,到手指离开屏幕所产生的一系列事件。
系统把事件封装为MotionEvent对象,事件分发的过程就是MotionEvent分发的过程。
事件序列:从手指按下屏幕开始,到手指离开屏幕所产生的一系列事件。
事件分发:用户通过屏幕与手机交互,每一次点击、长按、移动等都是一个事件
事件分发机制:某一个事件从屏幕传递各个View,由View来使用这一事件(消费事件)或者忽略这一事件(不消费事件),这整个过程的控制。
Activity的事件分发流程图。
dispatchtouchEvent(MotionEvent ev) 和 onTouchEvent(MotionEvent ev) 流程圖
事件什么情况下被消费,什么情况下被传递
事件分发对象:MotionEvent
MotionEvent对象包含的事件类型即动作
ACTION_DOWN 按下、ACTION_MOVE 移动、ACTION_UP抬起、ACTION_CANCEL取消
事件序列:从手指按下屏幕开始,到手指离开屏幕所产生的的一系列事件。
App传递层级
Activity并不负责视图的控制,只控制生命周期和处理事件,控制视图的是Window窗口,Window包含一个DecorView, DecorView代表一个顶级View,Activity中setContentView设置的view是DecorViewd的子view.
Activity->Window->DecorView->ViewGroup->View
主要传递对象及顺序
Activity->ViewGroup->View
源码查看的目的:
事件什么情况下被消费,什么情况下被传递
事件分发
通过手指对屏幕的触摸开完成整个交互过程
用户通过屏幕与手机交互的时候,每一次点击、长按、移动等都是一个事件
事件分发机制:某一个事件从屏幕传递各个View,由View来使用这一事件(消费事件)或者忽略这一事件(不消费事件),这整个过程的控制。
事件的类型
按下(ACTION_DOWN)
移动(ACTION_MOVE)
抬起 (ACTION_UP)
取消(ACTION_CANCEL)
事件序列
从手指按下屏幕开始,到手指离开屏幕所产生的一系列事件
传递层级
Activity->Window->DecorView->ViewGroup->View
主要传递对象及顺序
Activity、ViewGroup、View
View的事件分发流程图。