文章目录
Android 事件分发 系列文章目录
一、Activity 的事件传递
二、PhoneWindow 事件传递
三、DecorView 事件传递
四、ViewGroup 事件传递
一、Activity 的事件传递
手指触摸到 Android 手机屏幕时 , 先由硬件驱动层产生事件 , 然后传递到 Framework 层 , 之后传递到 AMS , 最后到 Activity 界面中 ;
在 Activity 界面中 , 会第一时间调用 dispatchTouchEvent 方法 , 然后会按照下图的层级 , 逐步向下分发触摸事件 ;
Activity | dispatchTouchEvent 分析 :
先判定该触摸事件是否是按下操作 , MotionEvent.ACTION_DOWN ;
触摸事件有 4 44 种操作 :
按下 : MotionEvent.ACTION_DOWN ;
移动 : MotionEvent.ACTION_MOVE ;
抬起 : MotionEvent.ACTION_UP ;
取消 : MotionEvent.ACTION_CANCEL , 手指移出组件边界 , 产生取消事件 ;
Activity | dispatchTouchEvent 源码示例 :
public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2, Window.OnWindowDismissedCallback, WindowControllerCallback, AutofillManager.AutofillClient { /** * Called to process touch screen events. You can override this to * intercept all touch screen events before they are dispatched to the * window. Be sure to call this implementation for touch screen events * that should be handled normally. * * @param ev The touch screen event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { // 判定是否是第一次按下 // 该方法与事件传递机制流程无关 // 提供给用户按下时可以执行的业务逻辑 onUserInteraction(); } // getWindow() 获取的是 PhoneWindow 窗口 // 调用 PhoneWindow 的 superDispatchTouchEvent ; if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); } public void onUserInteraction() { } }
源码地址 : /frameworks/base/core/java/android/app/Activity.java
二、PhoneWindow 事件传递
在上述 Activity 的 dispatchTouchEvent 方法中 , 调用了 PhoneWindow 的 superDispatchTouchEvent 方法 ;
Activity 的下一层是 PhoneWindow ;
PhoneWindow | superDispatchTouchEvent 源码 :
public class PhoneWindow extends Window implements MenuBuilder.Callback { // This is the top-level view of the window, containing the window decor. private DecorView mDecor; @Override public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); } }
源码路径 : /frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
三、DecorView 事件传递
在 PhoneWindow 的 superDispatchTouchEvent 方法中 , 调用了 DecorView 的 superDispatchTouchEvent 方法 ;
PhoneWindow 的下一层是 DecorView ;
DecorView | superDispatchTouchEvent 源码 :
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks { public boolean superDispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); } }
源码路径 : /frameworks/base/core/java/com/android/internal/policy/DecorView.java
四、ViewGroup 事件传递
DecorView 中的 superDispatchTouchEvent 中 , 调用父类的 superDispatchTouchEvent 方法 , 这里涉及到事件分发 superDispatchTouchEvent 方法的 DecorView 的父类是 ViewGroup ;
DecorView 是 FrameLayout 的子类 , FrameLayout 是 ViewGroup 的子类 ;
@UiThread public abstract class ViewGroup extends View implements ViewParent, ViewManager { @Override public boolean dispatchTouchEvent(MotionEvent ev) { } }