天天看點

ScrollView嵌套可滾動View

在實際項目需求中,經常會遇到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可以攔截。