一、方法的介紹:
onTouch: 該方法是onTouchListener的回調(diào)方法藐窄,在View的dispatchTouchEvent()方法中調(diào)用资昧;
onTouchEvent:View的內(nèi)部方法,在dispatchTouchEvent()方法中調(diào)用荆忍;
onClick:該方法是onClickListener的回調(diào)方法格带,在onTouchEvent中調(diào)。
方法執(zhí)行的先后順序: 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);
}
當一個事件傳遞到View時微宝,會首先執(zhí)行dispatchTouchEvent()方法棺亭。此時,先進入一個判斷芥吟,三個條件同時滿足侦铜,則返回true,不走onTouchEvent()方法钟鸵;否則返回Touch Event方法的執(zhí)行結(jié)果钉稍。
條件一:onTouchListener是否為空,看程序員是否set了onTouchListener棺耍;
條件二:該View是否enable(控件基本默認enable)贡未;
條件三:onTouch方法的返回值。
所以蒙袍,先走了onTouch方法俊卤。如條件一二都滿足,在onTouch中返回false害幅,則會走onTouchEvent方法消恍。
所以,再走onTouchEvent方法以现。onTouchEvenr方法中在ACTION_UP的事件下狠怨,執(zhí)行了performClick方法约啊,該方法如下:
public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
if (mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnClickListener.onClick(this);
return true;
}
return false;
}
不難解讀,當onClickListener不為空時佣赖,調(diào)用了onClick方法恰矩。
所以,最后走onClick方法憎蛤。
且onClick方法是在手指抬起來的時候去調(diào)用的外傅。
三.只有當dispatchTouchEvent方法在前一個Action返回true,后一個Action才會執(zhí)行俩檬。
如何解讀這句話萎胰??豆胸?
例如:
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);