事件分发简略版

65 阅读1分钟

Activity

dispatchTouchEvent -> child.dispatchTouchEvent

onTouchEvent

public boolean dispatchTouchEvent(MotionEventev) {
    if(child.dispatchTouchEvent(ev)) {
        // 如果子View消费了该事件,则返回TRUE,让调用者知道该事件已被消费
        return true;
    } else {
        // 如果子View没有消费该事件,则调用自身的onTouchEvent尝试处理。
        return onTouchEvent(ev);
    }
}

ViewGroup:View的子类

dispatchTouchEvent -> child.dispatchTouchEvent

onInterceptTouchEvent

View.onTouchEvent

   public boolean dispatchTouchEvent(MotionEventev) {
       if(!onInterceptTouchEvent(ev)) {
           // 不拦截,则传给子View进行分发处理
           if (child.dispatchTouchEvent(ev)) {
               return true;
           } else {
               // 交由父类View的dispatchTouchEvent方法处理,最后还是调用onTouchEvent
               return super.dispatchTouchEvent(ev);
           }
       } else {
           // 拦截事件,交由父类View的dispatchTouchEvent方法处理,最后还是调用onTouchEvent
           return super.dispatchTouchEvent(ev);
       }
   }

View

dispatchTouchEvent

onTouchEvent

public boolean dispatchTouchEvent(MotionEventev){
    //如果该对象的监听成员变量不为空,则会调用其onTouch方法,
    if(mOnTouchListener!=null && mOnTouchListener.onTouch(this,event)) {
        // 若onTouch方法返回TRUE,则表示消费了该事件,则dispachtouTouchEvent返回TRUE,让其调用者知道该事件已被消费。
        return true;
    }
    // 若监听成员为空或onTouch没有消费该事件,则调用对象自身的onTouchEvent方法处理。
    return onTouchEvent(ev);
}

综上所述:Activity->ViewGroup->View通过dispatchTouchEvent方法一层一层往下调用,再调用onTouchEvent方法回调boolean值(是否处理),如果没有处理再调用父级的onTouchEvent方法,类似View->ViewGroup->Activity

  • View的dispatchTouchEvent方法内会调用OnTouchListener对象的onTouch方法
  • View的onTouchEvent方法内会调用OnClickListener对象的onClick方法 所以onTouchListener对象的onTouch方法是优先于onClickListener对象的onClick方法调用的。

截屏2023-11-01 23.37.53.png