事件分发(一)Activity对触摸事件的分发流程

136 阅读1分钟

Activity对触摸事件的分发流程

本文源码基于Android 10.0

首先,用户触摸屏幕之后,会调用Activity的dispatchTouchEvent()方法:

​ViewDispatchActivity.java​

@Override  
public boolean dispatchTouchEvent(MotionEvent ev) {  
    Log.e("ViewDispatchActivity", "dispatchTouchEvent");  
    return super.dispatchTouchEvent(ev);  
}

也就是:​​Activity.java​

public boolean dispatchTouchEvent(MotionEvent ev) {  
    if (ev.getAction() == MotionEvent.ACTION\_DOWN) {  
        onUserInteraction();  
    }  
    if (getWindow().superDispatchTouchEvent(ev)) {  
        return true;  
    }  
    return onTouchEvent(ev);  
}

以上可知:

Activity.onUserInteraction()

1、如果事件类型为ACTION_DOWN按下操作,则会回调onUserInteraction()方法,表示用户正在与应用进行交互,可以在此实现与用户的交互功能。

​ViewDispatchActivity.java​

@Override  
public void onUserInteraction() {  
    Log.e("ViewDispatchActivity", "onUserInteraction");  
    super.onUserInteraction();  
}

​Activity.java​​也就是:

public void onUserInteraction() {  
}

ViewGroup.superDispatchTouchEvent()

2、如果Window抽象类的实现类PhoneWindow的superDispatchTouchEvent()方法返回true,则当前方法也返回true。

继续看下PhoneWindow,可知调用的是DecorView的superDispatchTouchEvent()方法:

​PhoneWindow.java​

@Override  
public boolean superDispatchTouchEvent(MotionEvent event) {  
    return mDecor.superDispatchTouchEvent(event);  
}

继续看下DecorView,可知调用的是ViewGroup的dispatchTouchEvent()方法:​​DecorView.java​

public boolean superDispatchTouchEvent(MotionEvent event) {  
    return super.dispatchTouchEvent(event);  
}

继续看下ViewGroup:​​ViewGroup.java​

@Override  
public boolean dispatchTouchEvent(MotionEvent ev) {  
 ......  
 return handled;  
}

由此,我们知道了Activity是如何将事件传递给ViewGroup的,并且知道了ViewGroup的dispatchTouchEvent()方法返回结果决定了Activity的dispatchTouchEvent()方法的返回结果。

Activity.onTouchEvent()

3、如果Window抽象类的实现类PhoneWindow的superDispatchTouchEvent()方法返回false,则调用onTouchEvent()方法。​​ViewDispatchActivity.java​

@Override  
public boolean onTouchEvent(MotionEvent event) {  
    Log.e("ViewDispatchActivity","onTouchEvent");  
    return super.onTouchEvent(event);  
}

也就是:​​Activity.java​

public boolean onTouchEvent(MotionEvent event) {  
    if (mWindow.shouldCloseOnTouch(this, event)) {  
        finish();  
        return true;  
    }  
    return false;  
}

以上可知,如果Window的shouldCloseOnTouch()方法返回true,则结束当前Activity,并且返回true;否则返回false。

继续看下Window的shouldCloseOnTouch()方法:​​Window.java​

public boolean shouldCloseOnTouch(Context context, MotionEvent event) {  
    final boolean isOutside =  
            event.getAction() == MotionEvent.ACTION\_UP && isOutOfBounds(context, event)  
            || event.getAction() == MotionEvent.ACTION\_OUTSIDE;  
    if (mCloseOnTouchOutside && peekDecorView() != null && isOutside) {  
        return true;  
    }  
    return false;  
}

以上可知,如果触摸事件在边界外,将会结束当前Activity,并且返回true,否则返回false。

总结