Android事件分发机制详解(一)

来源:互联网 发布:linux 视频剪辑 编辑:程序博客网 时间:2024/06/16 13:10

很重要的概念,网上搜集整理,深入学习.

事件分发的对象-MotionEvent

MotionEvent 对象是Android事件分发的核心概念,必须明白
当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件(Touch事件)。
Touch事件相关细节(发生触摸的位置、时间、历史记录、手势动作等)被封装成MotionEvent对象
○ MotionEvent.ACTION_DOWN:按下View(所有事件的开始
○ MotionEvent.ACTION_MOVE:滑动View
○ MotionEvent.ACTION_CANCEL:非人为原因结束本次事件
○ MotionEvent.ACTION_UP:抬起View(与DOWN对应)

任何事件列都是以DOWN事件开始,UP事件结束,中间有无数的MOVE事件,如下图:

事件分发的本质:
将点击事件(MotionEvent)向View进行传递,当前view处理获取传递给子view直到最后处理
即当一个点击事件发生后,系统需要将这个事件传递给一个具体的View去处理。这个事件传递的过程就是分发过程。

传递顺序从外到里传递
例如一个点击事件产生后,传递顺序是:Activity(Window) -> ViewGroup -> View

注意:View是所有UI组件的基类(ViewGroup是View的子类)
ViewGroup实际上也是一个View,只不过比起View,它多了可以包含子View和定义布局参数的功能(是容纳UI组件的容器,即一组View的集合可以包含很多子View和子VewGroup)

事件分发的核心方法

事件分发过程由dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()三个方法协助完成
所以这三个方法的深入理解也是学习的核心
消费事件:三个方法都会涉及到,核心返回true表示要处理事件,不要传递,false不消费事件,事件传递出去.
dispatchTouchEvent()
解释:

常说事件传递中的流程是:dispatchTouchEvent->onInterceptTouchEvent->onTouchEvent
在这个链条中dispatchTouchEvent()是处在链首的位置当然也是最重要的.
在dispatchTouchEvent()决定了Touch事件是由自己的onTouchEvent()处理
还是分发给子View处理让子View调用其自身的dispatchTouchEvent()处理.

事件消费

返回false,不消费事件,事件不会往下传递,将事件回传给父控件的onTouchEvent()处理
Activity例外:返回false=消费事件

onInterceptTouchEvent()

onInterceptTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件,这就是所谓的Intercept(截断)。
备注:ViewGroup独有方法(Activity、View都没该方法)
事件消费
返回false,不消费事件,
ture拦截事件自己的onTouchEvent执行

onTouchEvent()

onTouchEvent() 用于处理事件,返回值决定当前控件是否消费(consume)了这个事件。可能你要问是否消费了又区别吗,反正我已经针对事件编写了处理代码?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。

事件消费

false
不处理(消费)该事件
事件往上传递给父控件的onTouchEvent()处理
当前View不再接受此事件列的其他事件(Move、Up);
true处理事件

事件分发机制流程 ##

super:调用父类方法
true:消费事件,即事件不继续往下传递
false:不消费事件,事件也不继续往下传递 / 交由给父控件onTouchEvent()处理

深入理解
当一个点击事件发生时,调用顺序如
事件最先传到Activity的dispatchTouchEvent()进行事件分发
调用Window类实现类PhoneWindow的superDispatchTouchEvent()
调用DecorView的superDispatchTouchEvent()
最终调用DecorView父类的dispatchTouchEvent(),即ViewGroup的dispatchTouchEvent()

当一个点击事件发生时,事件最先传到Activity的dispatchTouchEvent()进行事件分发,最终是调用了ViewGroup的dispatchTouchEvent()方法
如果ViewGroup的dispatchTouchEvent()返回true就不执行Activity的onTouchEvent()方法;如果返回false,就执行。
这样事件就从 Activity 传递到了 ViewGroup

onTouch()和onTouchEvent()的区别

这两个方法都是在View的dispatchTouchEvent中调用,但onTouch优先于onTouchEvent执行。
如果在onTouch方法中返回true将事件消费掉,onTouchEvent()将不会再执行。

0 0
原创粉丝点击