事件分发机制详解

1 事件分发的对象是谁?

定义:当用户触摸屏幕时,将产生的触摸行为(Touch事件)
主要发生的 Touch 事件有如下四种:
MotionEvent.ACTION_DOWN:手指刚接触屏幕(所有事件的开始)
MotionEvent.ACTION_MOVE:手指在屏幕上面滑动
MotionEvent.ACTION_CANCEL:非人为因素取消
MotionEvent.ACTION_UP:手指从屏幕上松开

事件序列
正常情况下,一次手指触摸屏幕的行为会发出一系列点击事件
1、点击屏幕后立即松开,事件序列为DOWN->UP
2、点击屏幕滑动一会在松开,事件序列为DOWN->MOVE->...->MOVE->UP

事件分发机制详解_第1张图片

2、事件分发的本质

将点击事件(MotionEvent)向某个 View 进行传递并最终得到处理,而这个事件传递的过程就是分发过程。

3 事件在哪些对象之间进行传递?

一个点击事件产生后,传递顺序是:Activity(Window) —> ViewGroup —> View

事件分发机制详解_第2张图片
  • Android 的 UI 界面是由 Activity、ViewGroup、View 及其派生类组合而成的
  • View 是所有 UI 组件的基类
  • ViewGroup 是容纳 UI 组件的容器,即一组 View 的集合(包含很多子 View 和子 VewGroup)

ViewGroup 是 View 的子类,只不过比起 View,它多了可以包含子 View 和定义布局参数的功能。

4 事件分发过程由哪些方法协作完成?

由 dispatchTouchEvent() 、onInterceptTouchEvent() 和 onTouchEvent() 协作完成。

dispatchTouchEvent():用来进行事件分发,当点击事件能够传递给当前View时,该方法就会被调用
onInterceptTouchEvent():判断是否拦截事件(只存在于ViewGroup中,普通的View没有这个方法),在dispatchTouchEvent()内部调用
onTouchEvent() :处理点击事件,在dispatchTouchEvent()内部调用

事件分发机制详解_第3张图片

5 事件分发结论

  • 一个事件序列从手指接触屏幕到手指离开屏幕,在这个过程中产生一系列事件,以DOWN事件开始,中间含有不定数的MOVE事件,以UP事件结束。

  • 正常情况下,一个事件序列只能被一个View拦截并消耗。

  • 某个View一旦决定拦截,那么这事件序列都将由它的onTouchEvent处理,并且它的onInterceptTouchEvent不会再调用。

  • 某个View一旦开始处理事件,如果它不消耗ACTION_DOWN事件(onTouchEvent返回false),那么同一事件序列中其他事件都不会再交给它处理。并且重新交由它的父元素处理(父元素onTouchEvent被调用)。

  • 事件的传递过程是由外向内的,即事件总是先传递给父元素,然后在由父元素分发给子View,通过requestDisallowInterceptTouchEvent方法可以在子View中干预父元素的事件分发过程,但ACTION_DOWN除外。

  • ViewGroup默认不拦截任何事件,即onInterceptTouchEvent默认返回false。View没有onInterceptTouchEvent方法,一旦有点击事件传递给它,那么它的onTouchEvent方法就会被调用。

  • View的onTouchEvent默认会消耗事件(返回True),除非它是不可点击的(clickable和longClickable同时为false)。View的longClickable默认都为false,clickable要分情况,比如Button的clickable默认为true,TextView的clickable默认为false。

  • View的enable属性不影响onTouchEvent的默认属性返回值,哪怕一个View是disable状态,只要它的clickable或者longClickable有一个为true,那么它的onTouchEvent就返回ture。

  • onClick会影响的前提是当前View是可以点击的,并且收到了ACTION_DOWN和ACTION_UP的事件,并且受长按事件影响,当长按事件返回true时,onClick不会响应。

  • onLongClick在ACTION_DOWN里判断是否进行响应,要想执行长按事件该View必须是longClickable的并且设置了OnLongClickListener。

事件分发机制详解_第4张图片
事件分发机制详解_第5张图片
事件分发机制详解_第6张图片

通过查看安卓源码中View对dispatchTouchEvent的实现,可以知道onTouchListener(onTouch方法在其中)的接口的执行顺序是要先于onTouchEvent的,onTouch方法会先触发。如果onTouchListener中的onTouch方法返回true,表示此次事件已经被消费了,那onTouchEvent是接收不到消息的。

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

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

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