android中的每個ViewGroup的子類都具有三個和TouchEvent相關的方法:
1.public boolean dispatchTouchEvent(MotionEvent event) 這個方法用來分發TouchEvent
2.public boolean onInterceptTouchEvent(MotionEvent event) 這個方法用來攔截TouchEvent
3.public boolean onTouchEvent(MotionEvent event) 這個方法用來處理TouchEvent
注意:不是所有的View的子類,只有可以向裏面添加View的控件才需要分發,比如TextView它本身就是最小的view了,所以不用再向它的子視圖分發了,它也沒有子視圖了,所以它沒有dispatch和Intercept,只有touchEvent。舉一個簡單的例子:(一個activity,佈局中有一個button)
對button進行監聽
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", " onClick");
}
});
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("TAG", "onTouch " + event.getAction());
return false;
}
});
執行結果如下:
onTouch 0 相當與down
onTouch 1 相當於up
onClick 點擊事件
由上面的結果可以看出來:事件傳遞的順序是先經過onTouch,再傳遞到onClick
當onTouch return false說明你還沒消費onTouch事件,在執行完你onTouch裏面的代碼之後,onTouch事件並沒有結束
當onTouch return true時說明此次事件被onTouch給消費掉了,不會繼續向下傳遞了
接着看dispatchTouchEvent的源碼
/**
* Pass the touch screen motion event down to the target view, or this
* view if it is the target.
* @param event The motion event to be dispatched.
* @return True if the event was handled by the view, false otherwise.
*/
public boolean dispatchTouchEvent(MotionEvent event) {
if (!onFilterTouchEventForSecurity(event)) {
return false;
}
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}
1.OnTouchListener是在setOnTouchListener方法中設置的,事實上就是我們剛纔在Activity中設置的setOnTouchListener,也就是說只要我們給控件註冊了touch事件,mOnTouchListener就一定被賦值了
2.第二個條件是判斷控件是否是使能的,按鈕默認即使Enabled,所以爲true
3.第三個條件是關鍵,該條件會回調控件註冊touch事件時的onTouch方法,這裏關鍵就是看onTouch方法執行的返回值
還有一點要題型的是Touch事件的層級傳遞。如果給一個控件註冊了touch事件,每次點擊它的時候都會觸發一系列ACTION_DOWN,ACTION_MOVE,ACTION_UP等事件.如果你在執行ACTION_DOWN的時候返回了false,後面一系列其它的action就不會再得到執行了。簡單的說,就是當dispatchTouchEvent在進行事件分發的時候,只有前一個action返回true,纔會觸發後一個action。