Android - 从onTouch、onTouchEvent、onCLick三个方法引申至事件分发源码分析

一、方法的介绍:

onTouch: 该方法是onTouchListener的回调方法,在View的dispatchTouchEvent()方法中调用;

onTouchEvent:View的内部方法,在dispatchTouchEvent()方法中调用;

onClick:该方法是onClickListener的回调方法,在onTouchEvent中调。

方法执行的先后顺序: onTouch -> onTouchEvent -> onClick。

下面讲述,以上顺序如何得知。

二. View的dispatchTouchEvent方法分析

View的dispatchTouchEvent代码:

public boolean dispatchTouchEvent(MotionEvent event) {
   if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&mOnTouchListener.onTouch(this, event)) {
       return true;
   }
   return onTouchEvent(event);
}
  1. 当一个事件传递到View时,会首先执行dispatchTouchEvent()方法。此时,先进入一个判断,三个条件同时满足,则返回true,不走onTouchEvent()方法;否则返回Touch Event方法的执行结果。
    条件一:onTouchListener是否为空,看程序员是否set了onTouchListener;
    条件二:该View是否enable(控件基本默认enable);
    条件三:onTouch方法的返回值。
    所以,先走了onTouch方法。

  2. 如条件一二都满足,在onTouch中返回false,则会走onTouchEvent方法。
    所以,再走onTouchEvent方法。

  3. onTouchEvenr方法中在ACTION_UP的事件下,执行了performClick方法,该方法如下:

public boolean performClick() {
    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
    if (mOnClickListener != null) {
        playSoundEffect(SoundEffectConstants.CLICK);
        mOnClickListener.onClick(this);
        return true;
    }
    return false;
}

不难解读,当onClickListener不为空时,调用了onClick方法。
所以,最后走onClick方法。
且onClick方法是在手指抬起来的时候去调用的。

三.只有当dispatchTouchEvent方法在前一个Action返回true,后一个Action才会执行。
如何解读这句话???
例如:
1.若ACTION_DOWN事件返回false,此时dispatchTouchEvent方法直接返回true。那么肯定可以接收到后面的MOVE或者UP事件;
2.若ACTION_DOWN事件返回true,此时dispatchTouchEvent方法走onTouchEvent方法,而该方法中的逻辑是只要该View是可点击,均返回true。所以dispatchTouchEvent方法还是返回true,还是可以接收到后面的MOVE或者UP事件。

所以:这就解释了一个问题,为什么TextView或者ImageView在onTouch方法中,如果在ACTION_DOWN是返回了false,就无法接收到其他事件MOVE或者UP的原因。
解决办法就是将View设置为可点击:setClickable(true);

你可能感兴趣的:(Android - 从onTouch、onTouchEvent、onCLick三个方法引申至事件分发源码分析)