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 > 0) { // pull down currently
                    // if view support pull down, then request parent do not intercept touch event.
                    getParent().requestDisallowInterceptTouchEvent(canScrollVertically(-1));
                } else if (deltaY < 0) { // pull up currently
                    getParent().requestDisallowInterceptTouchEvent(canScrollVertically(1));
                }
                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可以拦截。

猜你喜欢

转载自blog.csdn.net/w_xue/article/details/77725293
今日推荐