Android事件传递机制和响应机制

205 阅读2分钟

Android 的触摸事件传递机制通过 dispatchTouchEvent() 方法从顶层视图(通常是 DecorView)开始,逐层传递到最底层的子视图。在 ViewGroup 中,可以通过 onInterceptTouchEvent() 方法(Activity和view无此事件)拦截事件中断从顶层到底层的传递过程。如果没有任何视图消费(即 onTouchEvent() 方法返回 false),事件会沿着相反的路径向上传递,直到最终被丢弃或由顶层视图消费。

事件传递机制

事件传递机制主要涉及以下三个方法,这些方法在视图层次结构中从顶层父视图向下传播到子视图:

  1. dispatchTouchEvent(MotionEvent event) : 这是事件分发的入口。每个视图都有这个方法。系统会首先调用根视图的 dispatchTouchEvent 方法,然后根据实现的逻辑,将事件传递给子视图的 dispatchTouchEvent 方法。

  2. onInterceptTouchEvent(MotionEvent event) : 这是 ViewGroup 专有的方法,用于拦截子视图的事件。如果 ViewGroup 的 onInterceptTouchEvent 返回 true,则表示该 ViewGroup 拦截事件,不会将事件传递给子视图,而是由自己处理。否则,事件将传递给子视图。

  3. onTouchEvent(MotionEvent event) : 当事件最终到达某个视图时,该视图会调用 onTouchEvent 方法处理事件。这个方法通常用于处理具体的触摸事件(如点击、滑动等)。如果视图返回 true,表示事件已被处理;否则,事件可能会继续传递到父视图。

示例:

Activity是顶层,装载了viewGroup的InterceptRelativeLayout, InterceptRelativeLayout再次装载。

点击事件分为down和up事件。

1.视图无拦截无消费。Activity第一次是down,无子视图消费第二次是up,第二次可能是因为Android事件优化不在派发到InterceptRelativeLayout和CustomTextView。

091018.073.png

2.InterceptRelativeLayout拦截但是未消费,CustomeTextView就不会被触发。且因为拦截了所以InterceptRelativeLayout会再次派发和消费up事件。

092153.236.png

3、InterceptRelativeLayout消费了但是并未拦截,顶层就显示无消费。

091739.332.png