事件分发机制

原帖:Android事件分发机制详解:史上最全面、最易懂 -

事件分发机制的主角


主角是谁呢?是点击事件,也叫touch事件。当用户触摸屏幕(View或ViewGroup派生的控件)将产生点击事件,Touch事件的相关细节(发生触摸的位置、时间等)被封装成MotionEvent对象


事件类型



事件分发机制_第1张图片
事件类型


从手指接触屏幕 至 手指离开屏幕,这个过程产生的一系列事件,大致过程如下:


事件分发机制_第2张图片
事件过程

即当一个点击事件(MotionEvent )产生后,系统需把这个事件传递给一个具体的 View去处理


事件分发的本质


将点击事件(MotionEvent)传递到某个具体的View 和 处理的整个过程就是分发过程


事件的传递


Activity、ViewGroup、View及其派生类组成


事件分发机制_第3张图片
UI界面


事件分发机制_第4张图片
三者的简要介绍


事件的分发顺序


一个点击事件发生后,事件先传到Activity,再传到ViewGroup,最终再传到View当中


事件分发过程中的协作方法


dispatchTouchEvent()   ——  事件分发

onInterceptTouchEvent()  ——  事件拦截

onTouchEvent()  ——  事件响应


事件分发机制_第5张图片
时间分发三大方法


事件分发机制的分析


由于之前说的事件的分发顺序是Activity -》 ViewGroup -》View,也就是说要分别分析Activity对点击事件的分发机制,ViewGroup对点击事件的分发机制,View对点击事件的分发机制,下面开始一个一个的分析



Activity的分发机制



事件分发机制_第6张图片

点击事件是DOWN意味着开始分发Activity中的事件,只要其中的getWindow.superDispatchTouchEvent返回true分发事件就结束了,而superDispatchTouchEvent返回的是顶层View(DecorView)的实例对象,而DecorView又是ViewGroup的子类,也就是说它实际调用了父类的方法也就是ViewGroup的dispatchTouchEvent(),这也实现了事件从Activity传到ViewGroup,至于ViewGroup为true/false就要看ViewGroup事件分发处理了,如果getWindow.superDispatchTouchEvent返回的是false,就进入onTouchEvent,该方法默认返回true,只有遇到处在边界外的消费事件才返回true,无论返回什么都结束Activity的事件分发


ViewGroup的分发机制


从Activity的事件分发我们可以知道ViewGroup分发机制从dispatchTouchEvent()开始


事件分发机制_第7张图片

当你点击了某个控件时,就调用该控件所在的布局,用onInterceptTouchEvent来判断是否拦截事件,如果返回true或者无View接受事件,就不允许事件向子View传递调用ViewGroup的父类dispatchTouchEvent,ViewGroup的父类是View,所以调用的是View.dispatchTouchEvent,他自己处理该事件,调用了自身的onTouch,onTouch又调用了onTouchEvent,在onTouchEvent中performClick处理了该事件,如果返回了false,就允许事件继续向子View传递,遍历ViewGroup中所有子View找到相应的子View控件,调用子View的dispatchTouchEvent将ViewGroup中的事件传递给View


View的分发机制


从ViewGroup事件分发机制知道,View事件分发机制从dispatchTouchEvent()开始


事件分发机制_第8张图片

当注册了监听器(mOnTouchListener 就不可能为 null),当前控件是否可以点击(由于很多View默认enable,故该条件恒定为true),mOnTouchListener.onTouch(this, event)如果该方法为true,三个条件为true后,View.dispatchTouchEvent()直接返回true,事件分发结束,如果返回false就会使得上述三个条件不全部成立,从而使得View.dispatchTouchEvent()中跳出If,执行onTouchEvent(event),在onTouchEvent(event)中,如果控件可以点击,一定返回true,否则返回false,用switch来判断点击的事件类型,是UP、DOWN、MOVE、CANCLE中的哪一个,加入是UP类型就调用performClick,再由其中的onClick为控件注册点击事件


总结


一般情况下,事件的分发都是由DOWN开始,调用Activity的dispatchTouchEvent,由这个方法向下传递事件给ViewGroup,一进ViewGroup就要判断是否用onInterceptTouchEvent拦截事件,不拦截就让传递给下层,下层的dispatchTouchEvent就会被调用,再问你是否拦截,直到事件被处理为止,拦截就将该事件交给当前View处理,也就是在onTouchEvent中处理点击事件,最后返回一个布尔值给dispatchTouchEvent告诉他是否已经处理,至此分发事件就到此结束了

你可能感兴趣的:(事件分发机制)