(四)Android事件分发机制 - 总结篇

  • (一)Android事件分发机制 - View篇
  • (二)Android事件分发机制 - ViewGroup篇
  • (三)Android事件分发机制 - Activity篇
  • (四)Android事件分发机制 - 总结篇

Android事件分发中三个重要方法:

public boolean dispatchTouchEvent(MotionEvent event)

dispatchTouchEvent用来进行事件的分发。如果事件能够传递给当前的View,那么此方法一定会被调用,返回结果表示是否分发当前事件。

public boolean onInterceptTouchEvent(MotionEvent ev)

onInterceptTouchEventViewGroup提供的方法,返回结果表示是否拦截当前事件(默认返回false),如果当前View拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,

public boolean onTouchEvent(MotionEvent event)

onTouchEventdispatchTouchEvent方法中被调用,用来处理点击事件,返回结果表示是否消耗当前事件(默认返回true),如果不消耗,则在同一个事件序列中,当前View无法再次接受到事件。

三个方法的分布情况:
  • (四)Android事件分发机制 - 总结篇_第1张图片

阅读Android事件分发的源代码(6.0版本)

  • 一个事件序列是指从手指触摸屏幕开始,到手指离开屏幕结束,这个过程中产生的一系列事件。同一个事件序列是以ACTION_DOWN事件开始,中间含有数量不定的ACTION_MOVE事件,最终以ACTION_UP事件结束;
  • 事件传递的顺序是:Activity -> Window -> View,即事件总是先传递给Activity,然后在传递给Window,最后在传递给View,顶级View接收到事件后,就会按照事件分发机制去分发事件;
  • 事件的传递过程是由外向内的,即事件总是由父元素分发给子元素;
  • 正常情况下,一个事件序列只能被一个View拦截且消耗。一旦一个View拦截了某次事件,那么同一个事件序列内的所有事件都会直接交给它处理,因此同一个事件序列中的事件不能分别由两个View同时处理,但是通过特殊手段可以做到,比如一个View将本该自己处理的事件通过onTouchEvent强行传递给其他View处理;
  • 某个View一旦开始处理事件,如果它不消耗ACTION_DOWN事件,那么同一事件序列的其他事情都不会再交给它来处理,并且事件将重新交给它的父容器去处理(调用父容器的onTouchEvent方法);
  • 某个View一旦开始处理事件,如果它消耗ACTION_DOWN事件,但是不消耗其他类型事件,那么这个点击事件会消失,父容器的onTouchEvent方法不会被调用,当前view依然可以收到后续的事件,但是这些事件最后都会传递给Activity处理;
  • 点击事件分发是到达顶级View后(一般是ViewGroup),会首先调用dispatchTouchEvent方法,其中它的onInterceptTouchEvent方法如果返回true,则会对事件传递进行拦截,事件由ViewGroup处理;如果onInterceptTouchEvent方法返回false,则代表不对事件进行拦截(默认返回false),此时子View中的dispatchTouchEvent方法将被调用,到此,事件已经由顶级View传递给了下一层的View,接下来的过程是一个递归循环的过程,和顶级View事件分发过程是一致的,直到完成整个事件分发。

事件分发的具体应用示例:

Android不规则点击区域详解


你可能感兴趣的:((四)Android事件分发机制 - 总结篇)