Touch Event事件分发流程

Android中的Touch Event分发流程从Activity开始,经过Window,再传递到View。Activity的dispatchTouchEvent()将事件交给Window处理,PhoneWindow的superDispatchTouchEvent()进一步分发。ViewGroup的dispatchTouchEvent()和onInterceptTouchEvent()决定了事件是否被拦截并处理。View的onTouchEvent()根据ACTION_DOWN、ACTION_MOVE和ACTION_UP进行不同操作,如设置点击检测、长按检测等。
摘要由CSDN通过智能技术生成

Touch Event的分发

点击事件的传递顺序是Activity->Window->View,从上到下依次传递。如果最底层的那个View的onTouchEvent返回false,那就说明这个View不想处理该事件,最终向上传递,让Activity自己来处理。

Touch事件的分发是从dispatchTouchEvent()方法开始的。首先来看下Activity的dispatchTouchEvent()。

1. Activity的dispatchTouchEvent()方法

 /**
 * 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) {
    //如果action是ACTION_DOWN,则调用onUserInteraction方法指示有触摸事件发生
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    // 调用PhoneWindow的superDispatchTouchEvent方法,将event分发给Window处理。如果返回false,则说明window或者view没有消费该事件,只能有该Activity来处理该事件。
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    //如果window或view没有消费该event,则由该Activity的onTouchEvent来处理。
    return onTouchEvent(ev);
}

/**
* 当一个key事件、触摸事件、滑动球事件发送到该Activity时,会回* 调该方法。
*/
public void onUserInteraction() {
}

从Activity的dispatchTouchEvent可以看到,它会把event传递给Window处理,并根据处理结果来决定是否需要自己来最终处理。如果需要Activity来处理,则调用Activity的onTouchEvent()方法。

/**
 * Called when a touch screen event was not handled by any of the views
 * under it.  This is most useful to process touch events that happen
 * outside of your window bounds, where there is no view to receive it.
 *
 * @param event The touch screen event being processed.
 *
 * @return Return true if you have consumed the event, false if you haven't.
 * The default implementation always returns false.
 */
public boolean onTouchEvent(MotionEvent event) {
    if (mWindow.shouldCloseOnTouch(this, event)) {
        finish();
        return true;
    }

    return false;
}

2. PhoneWindow的superDispatchTouchEvent()方法

Window中的superDispatchTouchEvent()方法是一个抽象方法,具体由它的子类PhoneWindow来实现。

@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
    //调用DecorView的superDispatchTouchEvent方法
    return mDecor.superDispatchTouchEvent(event);
}

public boolean superDispatchTouchEvent(MotionEvent event) {
    //调用到ViewGroup的dispatchTouchEvent事件中
    return super.dispatchTouchEvent(event);
}

3.ViewGroup的dispatchTouchEvent()

ViewGroup处理点击事件的大致流程如下:如果ViewGroup接受了一个点击事件,那么首先会调用他的dispatchTouchEvent方法,接着调用ViewGroup的onInterceptTouchEvent方法,如果onInterceptTouchEvent方法返回true,那就代表要拦截这个事件。接下来这个事件就给ViewGroup自己处理了,从而ViewGroup的onTouchEvent方法会被调用。

如果这个ViewGroup的onInterceptTouchEvent反复false,就代表ViewGroup不拦截这个事件,然后把这个事件传递给自己的子元素,然后子元素的dispatchTouchEvent就会被调用,就这样一直循环直到事件被处理。

用伪代码来表示如下:

public boolean dispatchTouchEvent(MotionEvent ev){
    boolean consume = false;
    //判断ViewGroup是否拦截
    if(onInterceptTouchEvent(ev)){
        //如果拦截的话,则由它的onTouchEvent来实现
        consume = onTouchEvent(ev);
    }else{
        //如果不拦截,则由它的子View来处理
        consume = child.dispatchTouchEvent(ev);
    }
    return consume;
}

ViewGroup的dispatchTouchEvent的源码如下:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (mInputEventConsistencyVerifier != null) {
        mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
    }
    ......

    boolean handled = false;
    if (onFilterTouchEventForSecurity(ev)) {
        final int action = ev.getAction();
        //action的掩码
        final int actionMasked = action & MotionEvent.ACTION_MASK;

        // Handle an initial down.
        // 处理初始的状态
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值