美文网首页
关于安卓recyclerview的子布局中,scrollview

关于安卓recyclerview的子布局中,scrollview

作者: motosheep | 来源:发表于2022-09-16 17:17 被阅读0次

    场景

    recyclerivew使用PagerSnapHelper,子布局中,使用scrollview,观察,scrollview内容
    区域超过高度时,滑动失效。

    原因

    recyclerview的触摸事件,没有分发到scrollview中,导致了scrollview的触摸事件失效。

    解决方法

    (1)当scrollview不需要滑动的时候,无需处理
    (2)当scrollview需要滑动的时候,需要捕获触摸事件。对于捕获的事件后,需要判断
    scrollview是否已经处于顶部/底部,若是,则不再处理触摸事件,否则需要处理触摸事件。

    实现

    (1)判断scrollview是否满足滑动的条件,原理是计算scrollview的子类总高度,再对比当前
    scrollview的高度,判断是否满足,核心代码如下:

    /**
     * 所有子布局高度
     */
    private int getChildHeight() {
        if (getChildCount() == 0) {
            return 0;
        }
        int result = 0;
        for (int i = 0; i < getChildCount(); i++) {
            result = result + getChildAt(i).getMeasuredHeight();
        }
        return result;
    }
    
    /**
     * 是否有超出内容
     */
    private boolean outSide() {
        return getChildHeight() > getMeasuredHeight();
    }
    

    (2)对scrollview进行滑动监听,初始化滑动到顶部/底部的变量,核心代码如下:

    setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            try {
                if (scrollY > oldScrollY) {
                    // 向下滑动
                }
                if (scrollY < oldScrollY) {
                    // 向上滑动
                }
                if (scrollY == 0) {
                    // 顶部
    //                        LogUtil.d("PagerSnapScrollView onScrollChange top");
                    mIsTop = true;
                } else {
    //                        LogUtil.d("PagerSnapScrollView onScrollChange top2");
                    mIsTop = false;
                }
                if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
                    //底部
    //                        LogUtil.d("PagerSnapScrollView onScrollChange bottom");
                    mIsBottom = true;
                } else {
    //                        LogUtil.d("PagerSnapScrollView onScrollChange bottom2");
                    mIsBottom = false;
                }
            } catch (Exception e) {
    
            }
        }
    });
    

    (3)最后,在scrollview的事件分发中,进行分发的处理,核心代码如下:

    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            if (outSide()) {
                switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mDownY = (int) ev.getY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int endY = (int) ev.getY();
                        if ((mIsBottom && (mDownY > endY))) {
                            setDisallowIntercept(false);
                            return super.dispatchTouchEvent(ev);
                        }
                        if ((mIsTop && mDownY < endY)) {
                            setDisallowIntercept(false);
                            return super.dispatchTouchEvent(ev);
                        }
                        setDisallowIntercept(true);
                        return super.dispatchTouchEvent(ev);
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        return super.dispatchTouchEvent(ev);
                }
                setDisallowIntercept(false);
                return super.dispatchTouchEvent(ev);
            } else {
                return super.dispatchTouchEvent(ev);
            }
        }
    

    that's all------------------------------------

    代码地址,类名PagerSnapScrollView

    相关文章

      网友评论

          本文标题:关于安卓recyclerview的子布局中,scrollview

          本文链接:https://www.haomeiwen.com/subject/sprdortx.html