引用: https://developer.android.com/training/gestures/viewgroup.html
對ViewGroup和它的子View來說扛禽,觸摸事件的處理方式是不一樣的却嗡±驶玻可以通過重載View Group的 onInterceptTouchEvent() 方法拓哺,來確保ViewGroup及各個子View能正確相應(yīng)觸摸事件。
ViewGroup攔截觸摸事件
不管是觸摸ViewGroup或它的子View,onInterceptTouchEvent()方法都會調(diào)用炉旷。該方法返回true, 則子View收不到Touch Event,執(zhí)行ViewGroup的 onTouchEvent()叉讥。 如果返回false窘行,則向子控件傳遞,調(diào)用相應(yīng)的子View的 onTouchEvent()方法图仓。
public class MyViewGroup extends ViewGroup {
private int mTouchSlop;
...
ViewConfiguration vc = ViewConfiguration.get(view.getContext());
mTouchSlop = vc.getScaledTouchSlop();
...
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
* 此方法判斷是否需要攔截觸摸事件罐盔,如果是滑動操作,則返回true救崔,運行本類的 onTouchEvent惶看。
*/
final int action = MotionEventCompat.getActionMasked(ev);
// 先處理觸摸完成的情況
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
// Release the scroll.
mIsScrolling = false;
return false; // 不攔截Touch Event捏顺,讓子View 處理
}
switch (action) {
case MotionEvent.ACTION_MOVE: {
if (mIsScrolling) {
// 如果正在滑動,則攔截Touch Event
return true;
}
// 判斷手指橫向移動超過一定距離纬黎,則開始滾動
// 需要讀者自己實現(xiàn) :)
final int xDiff = calculateDistanceX(ev);
// Touch slop should be calculated using ViewConfiguration
// constants.
if (xDiff > mTouchSlop) {
// 開始滾動!
mIsScrolling = true;
return true;
}
break;
}
...
}
// 通常情況下不攔截Touch Event幅骄,讓子View來處理
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// 這里我們開始處理touch event (e.g. 如果action是ACTION_MOVE,滾動container)。intercepted in
// 這個方法只有在touch event在onInterceptTouchEvent中被截獲時調(diào)用
...
}
}