public boolean dispatchTouchEvent(MotionEvent event){ ... ... if(onFilterTouchEventForSecurity(event)){ ListenerInfo li = mListenerInfo; if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { //(1)onTouch调用 return true; } if(onTouchEvent(event)){ //(2)onTouchEvent调用 return true; } } ... ... return false; }
public boolean onTouchEvent(MotionEvent event) { ...... switch (action) { case MotionEvent.ACTION_UP: ...... performClick(); ...... break; ...... } public boolean performClick() { final boolean result; final ListenerInfo li = mListenerInfo; if (li != null && li.mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); li.mOnClickListener.onClick(this); result = true; } else { result = false; } sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); return result; }(1)如果没有设置OnClickListener,只设置了OnTouchListener,那么在代码(1)处就会调用onTouch,如果DOWN事件时返回了true,那么剩下的事件都会交由此View进行处理;如果返回了false,那么就会执行代码(2)处的
onTouchEvent
函数,如果设置了OnClickListener,就会在其中进行调用,如果没有设置,
dispatchTouchEvent
就会返回false,那么剩下的事件都不会交由此View进行处理;
(2)如果同时设置了OnTouchListener与OnClickListener,那么我们再按上面的两种情况进行分析:
情况1:onTouch在DOWN时返回了true,那么代码(1)处就得到了真的结果,直接就返回了true,可以知道后面代码(2)处的
onTouchEvent
函数不会被执行,那么自然你的OnClickListener就不起作用了,onClick就不会被执行;
情况2:onTouch在DOWN时返回了false,那么代码(1)处就不会得到真的结果,后面代码(2)处的
onTouchEvent
函数就会得到执行,而如果你设置了OnClickListener,View就会处于CLICKABLE状态,那么
onTouchEvent
函数就会返回true,
dispatchTouchEvent
就会返回true,那么这时后面的事件由于DOWN时返回true,就会统统交由此View进行处理,自然你的onTouch中也能够监听到后面的所有事件!这样上面的情况就能够得到解释了。