解决NestedScrollView嵌套RecycleView的bug

来源:互联网 发布:阿里云备案流程图 编辑:程序博客网 时间:2024/04/30 06:19

正常情况下NestedScrollView嵌套RecycleView,一是会出现只显示一行的情况,二是滑动异常即事件冲突。

解决方法:

1.也是最简单的方法,把design库和V7库升级到23.2以上,注意加上以下代码

 mLinearLayoutManager.setSmoothScrollbarEnabled(true);        mLinearLayoutManager.setAutoMeasureEnabled(true);        cardslist_view.setLayoutManager(mLinearLayoutManager);        cardslist_view.setHasFixedSize(true);        cardslist_view.setNestedScrollingEnabled(false);
问题即可解决。

2.麻烦一点,重写LinearLayoutManager和NestedScrollView。

public class CustomLinearLayoutManager extends LinearLayoutManager {    public CustomLinearLayoutManager(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);        int width = 0;        int height = 0;        for (int i = 0; i < getItemCount(); i++) {            if (getOrientation() == HORIZONTAL) {                measureScrapChild(recycler, i,                        View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),                        heightSpec,                        mMeasuredDimension);                width = width + mMeasuredDimension[0];                if (i == 0) {                    height = mMeasuredDimension[1];                }            } else {                measureScrapChild(recycler, i,                        widthSpec,                        View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),                        mMeasuredDimension);                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) {        View view = recycler.getViewForPosition(position);        recycler.bindViewToPosition(view, position);        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);        }    }}
public class MyNestedScrollView extends NestedScrollView {    private int downX;    private int downY;    private int mTouchSlop;    public MyNestedScrollView(Context context) {        super(context);        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();    }    public MyNestedScrollView(Context context, AttributeSet attrs) {        super(context, attrs);        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();    }    public MyNestedScrollView(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);    }}



3 0
原创粉丝点击