一 事件分发流程
被分发的对象是哪些?被分发的对象是用户触摸屏幕而产生的点击事件,事件主要包括:按下、滑动、抬起和取消。这些事件被封装成MotionEvent对象。该对象中的主要事件如下:
事件传递的顺序为:Activity -> Window ->DecorView(当前界面的底层容器)。一个点击操作要是没有被Activity下的任何View处理,即顶层DecorView的dispatchTouchEvent()方法返回false的话,则Activity的onTouchEvent()方法会被调用。
我们下面在源码中追踪下。
当我们点击手机屏幕的时候,硬件会通知软件,软件底层程序(C/C++)会调用java层Activity的dispatchTouchEvent(MotionEvent ev)方法。
public boolean dispatchTouchEvent(MotionEvent ev) {
//如果是down,说明是一个新的事件
3398 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
3399 onUserInteraction();
3400 }
//调用了PhoneWindow的superDispatchTouchEvent()方法,
//把事件从Activity分发到DecorView
//如果找不到消费当前事件的View,getWindow().superDispatchTouchEvent(ev)会返回false
3401 if (getWindow().superDispatchTouchEvent(ev)) {
3402 return true;
3403 }
//返回Activity的onTouchEvent
3404 return onTouchEvent(ev);
3405 }
3406
我们看下 onUserInteraction();
public void onContentChanged() {
}
这是一个空房法,开发者可以实现这个方法,屏幕点击按下的时候,可以再这里增加逻辑
getWindow()这里返回的是一个Window对象。在Window对象中superDispatchTouchEvent(ev)方法是一个抽象方法,在其子类PhoneWindow中实现。我们看下PhoneWindow中superDispatchTouchEvent(ev)方法。
1828 @Override
1829 public boolean superDispatchTouchEvent(MotionEvent event) {
1830 return mDecor.superDispatchTouchEvent(event);
1831 }
mDecor是DecorView对象
我们进入DecorView对象中
439 public boolean superDispatchTouchEvent(MotionEvent event) {
440 return super.dispatchTouchEvent(event);
441 }
DecorView的父类是ViewGroup,所以 super.dispatchTouchEvent(event)调用的是ViewGroup里的方法。
我们暂且不去管ViewGroup,回过头来看看Activity的dispatchTouchEvent的返回值onTouchEvent(ev);
3401 if (getWindow().superDispatchTouchEvent(ev)) {
3402 return true;
3403 }
假设这段代码不执行,即getWindow().superDispatchTouchEvent(ev)返回为false;
就会执行 onTouchEvent(ev)
二 事件分发原理解析
三 事件拦截
来源:CSDN
作者:qczg_wxg
链接:https://blog.csdn.net/qczg_wxg/article/details/103768435