在實際項目需求中,經常會遇到ScrollView嵌套縱向可滾動的View,比如ListView,TextView。在預設情況下,ScrollView檢測到縱向有滾動就會intercept touch事件然後滾動自身,導緻子View根本無法滾動。
網友的大部分做法是在子View檢測到Down事件時馬上requestDisallowInterceptTouchEvent,檢測到Up事件時再取消request。實際效果存在一個問題,如果子View本身内容比較少,根本不需要滾動,此時會發現手指在上面滾動時沒有效果。
下面的示例稍作改動,僅在子View可滾動的情況下才請求parent不要攔截事件,在滾動完畢後告訴parent可以攔截事件。
同樣是複寫子View的OnTouchEvent,當然調用子View的setOnTouchListener也是一樣的
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// do nothing
break;
case MotionEvent.ACTION_MOVE:
int deltaY = (int) (event.getY() - lastY);
if (deltaY > ) { // pull down currently
// if view support pull down, then request parent do not intercept touch event.
getParent().requestDisallowInterceptTouchEvent(canScrollVertically(-));
} else if (deltaY < ) { // pull up currently
getParent().requestDisallowInterceptTouchEvent(canScrollVertically());
}
break;
case MotionEvent.ACTION_UP:
// reset state
getParent().requestDisallowInterceptTouchEvent(false);
break;
case MotionEvent.ACTION_CANCEL:
// parent has intercepted the touch event
break;
}
lastY = event.getY();
// call super to process scrolling
return super.onTouchEvent(event);
}
外面隻需要根據deltaY計算出使用者滑動方向,然後判斷該方向上是否可以滑動,是則告訴parent不要攔截事件,否則告訴parent可以攔截。