ScrollView嵌套recyclerView问题

记得以前在解决scrollView与ListView嵌套问题时,那个时候是自定义了listView去测量listView高度,今天项目中刚好碰到了要用recycerView,同样也是嵌套在scrollView中,但是按照以前listView方法居然不显示了,后来发现原来是要重写的是LayoutManager…

重写的LinearLayoutManager

public class FullyLinearLayoutManager extends LinearLayoutManager {  

    private static final String TAG = FullyLinearLayoutManager.class.getSimpleName();  

    public FullyLinearLayoutManager(Context context) {  
        super(context);  
    }  

    public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {  
        super(context, orientation, reverseLayout);  
    }  

    private int[] mMeasuredDimension = new int[2];  

    @Override  
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,  
                          int widthSpec, int heightSpec) {  

        final int widthMode = View.MeasureSpec.getMode(widthSpec);  
        final int heightMode = View.MeasureSpec.getMode(heightSpec);  
        final int widthSize = View.MeasureSpec.getSize(widthSpec);  
        final int heightSize = View.MeasureSpec.getSize(heightSpec);  

        Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode  
                + " \nheightMode " + heightSpec  
                + " \nwidthSize " + widthSize  
                + " \nheightSize " + heightSize  
                + " \ngetItemCount() " + getItemCount());  

        int width = 0;  
        int height = 0;  
        for (int i = 0; i < getItemCount(); i++) {  
            measureScrapChild(recycler, i,  
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),  
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),  
                    mMeasuredDimension);  

            if (getOrientation() == HORIZONTAL) {  
                width = width + mMeasuredDimension[0];  
                if (i == 0) {  
                    height = mMeasuredDimension[1];  
                }  
            } else {  
                height = height + mMeasuredDimension[1];  
                if (i == 0) {  
                    width = mMeasuredDimension[0];  
                }  
            }  
        }  
        switch (widthMode) {  
            case View.MeasureSpec.EXACTLY:  
                width = widthSize;  
            case View.MeasureSpec.AT_MOST:  
            case View.MeasureSpec.UNSPECIFIED:  
        }  

        switch (heightMode) {  
            case View.MeasureSpec.EXACTLY:  
                height = heightSize;  
            case View.MeasureSpec.AT_MOST:  
            case View.MeasureSpec.UNSPECIFIED:  
        }  

        setMeasuredDimension(width, height);  
    }  

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,  
                                   int heightSpec, int[] measuredDimension) {  
        try {  
            View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException  

            if (view != null) {  
                RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();  

                int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,  
                        getPaddingLeft() + getPaddingRight(), p.width);  

                int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,  
                        getPaddingTop() + getPaddingBottom(), p.height);  

                view.measure(childWidthSpec, childHeightSpec);  
                measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;  
                measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;  
                recycler.recycleView(view);  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
        }  
    }  
}  

以及重写的GridViewLayout:

public class FullyGridLayoutManager extends GridLayoutManager {  

    private int mwidth = 0;  
    private int mheight = 0;  

    public FullyGridLayoutManager(Context context, int spanCount) {  
        super(context, spanCount);  
    }  

    public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {  
        super(context, spanCount, orientation, reverseLayout);  
    }  

    private int[] mMeasuredDimension = new int[2];  

    public int getMwidth() {  
        return mwidth;  
    }  

    public void setMwidth(int mwidth) {  
        this.mwidth = mwidth;  
    }  

    public int getMheight() {  
        return mheight;  
    }  

    public void setMheight(int mheight) {  
        this.mheight = mheight;  
    }  

    @Override  
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {  
        final int widthMode = View.MeasureSpec.getMode(widthSpec);  
        final int heightMode = View.MeasureSpec.getMode(heightSpec);  
        final int widthSize = View.MeasureSpec.getSize(widthSpec);  
        final int heightSize = View.MeasureSpec.getSize(heightSpec);  

        int width = 0;  
        int height = 0;  
        int count = getItemCount();  
        int span = getSpanCount();  
        for (int i = 0; i < count; i++) {  
            measureScrapChild(recycler, i,  
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),  
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),  
                    mMeasuredDimension);  

            if (getOrientation() == HORIZONTAL) {  
                if (i % span == 0) {  
                    width = width + mMeasuredDimension[0];  
                }  
                if (i == 0) {  
                    height = mMeasuredDimension[1];  
                }  
            } else {  
                if (i % span == 0) {  
                    height = height + mMeasuredDimension[1];  
                }  
                if (i == 0) {  
                    width = mMeasuredDimension[0];  
                }  
            }  
        }  

        switch (widthMode) {  
            case View.MeasureSpec.EXACTLY:  
                width = widthSize;  
            case View.MeasureSpec.AT_MOST:  
            case View.MeasureSpec.UNSPECIFIED:  
        }  

        switch (heightMode) {  
            case View.MeasureSpec.EXACTLY:  
                height = heightSize;  
            case View.MeasureSpec.AT_MOST:  
            case View.MeasureSpec.UNSPECIFIED:  
        }  
        setMheight(height);  
        setMwidth(width);  
        setMeasuredDimension(width, height);  
    }  

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,  
                                   int heightSpec, int[] measuredDimension) {  
        if (position < getItemCount()) {  
            try {  
                View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException  
                if (view != null) {  
                    RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();  
                    int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,  
                            getPaddingLeft() + getPaddingRight(), p.width);  
                    int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,  
                            getPaddingTop() + getPaddingBottom(), p.height);  
                    view.measure(childWidthSpec, childHeightSpec);  
                    measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;  
                    measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;  
                    recycler.recycleView(view);  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}  

重写完之后,用就好说了,在adapter的onBindview和平常一样用就可以了

final FullyGridLayoutManager manager = new FullyGridLayoutManager(context.getActivity(), 3);  
       manager.setOrientation(GridLayoutManager.VERTICAL);  
       manager.setSmoothScrollbarEnabled(true);  
       viewHolder.recyclerView.setLayoutManager(manager);  

关键是,还有个坑爹的问题:
此种方法在4.x系统上好用,能显示滑动也流畅,但是在5.x上虽然显示正常,但是滑动的时候好像被粘住了,没有惯性效果。。。。
最后解决方法是重写最外层的Scrollview

**  
 * 屏蔽 滑动事件  
 */  
public class MyScrollview extends ScrollView {  
    private int downX;  
    private int downY;  
    private int mTouchSlop;  

    public MyScrollview(Context context) {  
        super(context);  
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
    }  

    public MyScrollview(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
    }  

    public MyScrollview(Context context, AttributeSet attrs, int defStyleAttr) {  
        super(context, attrs, defStyleAttr);  
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
    }  

    @Override  
    public boolean onInterceptTouchEvent(MotionEvent e) {  
        int action = e.getAction();  
        switch (action) {  
            case MotionEvent.ACTION_DOWN:  
                downX = (int) e.getRawX();  
                downY = (int) e.getRawY();  
                break;  
            case MotionEvent.ACTION_MOVE:  
                int moveY = (int) e.getRawY();  
                if (Math.abs(moveY - downY) > mTouchSlop) {  
                    return true;  
                }  
        }  
        return super.onInterceptTouchEvent(e);  
    }  
}  

卡顿问题 ,不用这么麻烦在重写

设置 :recyclerView.setNestedScrollingEnabled(false); 即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值