首先看下圖:
有沒有對2,6感到很奇怪?怎麼會觸發onLongClick事件,並且按鈕還是不擡起的狀態?
其實:
1.優先級 : OnTouchListener > onTouchEvent
public boolean dispatchTouchEvent(MotionEvent event) {
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}
2.返回值對事件的消費
返回false表示touch事件在當前方法未被消費完,還會傳給下一個方法。
返回true,表示touch事件在當前方法被消費完,不會傳給下一個方法。
3.action事件的執行順序
dispatchTouchEvent在進行事件分發的時候,只有前一個action返回true,纔會觸發後一個action。
如果你在執行ACTION_DOWN的時候返回了false,後面一系列其它的action就不會再得到執行了
4.爲什麼onTouch中返回down返回了false,還會執行up事件?
根據第2點,如果onTouc返回false,就會傳遞到onTouchEvent中,只要按鈕可點擊(clickable,Long_clickable,context_clickable任意一個爲true),onTouchEvent就會返回true,所以接下來的action事件還是可以繼續接收的
5.onLongClick和onClick的執行時間
其實在onTouchEvent中,在ActionDown時會進行記時操作,來判斷是短按還是長按(500ms)
onClick事件是在onTouchEvent 的ActionUp後響應的
6.什麼時候會停止計時
在actionMove時,移出了view的顯示範圍
actionUp
最後,關於onTouch中down返回false,up返回true,爲什麼會觸發onLongClick以及按鈕不擡起的問題
- onTouch的down返回false,說明onTouch不消費,傳遞給OnTouchEvent的ActionDown執行,這時開啓500ms計時(參考第5條),並返回true(參考第4條),接下來的事件還能接受
- 接着擡手,觸發onTouch的up,返回true,這時onTouch自己消費了這個事件,不會傳遞給onTouchEvent了,但是計時還在繼續,所以過一會執行了onLongClick,按鈕還是press狀態
- 總結,都怪onTouch給onTouchEvent開了門,忘了關窗
參考:
http://blog.csdn.net/guolin_blog/article/details/9097463
http://www.cnblogs.com/Tiger-Dog/articles/1944791.html
http://blog.csdn.net/eclipsexys/article/details/8785149
http://www.devwiki.net/2015/06/18/Android-View-Click-Event/