NestedScrollView多层嵌套滑动冲突解决

一个完整的xml布局,里面嵌套了,多个recycleview,另外配合AppBarLayout,形成一个向上滑动头部具隐藏,toolbar显示的效果。
bug:也不能说bug,只是界面滑动时,因为滑动冲突造成的卡顿、不自然。

思路:根据需求,让界面形成一个完整的界面。
参考:NestedScrollView
NestedScrollView与ScrollView相比,唯一的区别就是,ScrollView嵌套recycleview有不可避免地滑动冲突;NestedScrollView在这里虽然也可以满足形成一个“界面”,不会产生滑动冲突,子view滑动,父view不滑动,但是我需要子view完全一点滑动能力都没有,不然会和AppBarLayout形成一个卡顿的现象。------这也是问题所在。

解决:自定义MyNestedScrollView,拦截滑动事件。(屏幕的事件传递是由window向上传递,先到父view再到子view)

//MyNestedScrollView

/**
 * Created by cc on 17-7-27.
 */
public class MyNestedScrollView extends NestedScrollView {
    private int downX;
    private int downY;
    private int mTouchSlop;
    private ScrollInterface scrollInterface;

    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;//返回true为拦截,父view消费滑动事件
                }
        }
        return super.onInterceptTouchEvent(e);
    }

    /*定义滑动接口*/
    public interface ScrollInterface{
        void onScrollChange(int scrollX, int scrollY, int oldScrollX, int oldScrollY);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        if (scrollInterface != null) {
            scrollInterface.onScrollChange(l, t, oldl, oldt);
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }

    public void setOnScrollChangeListener(ScrollInterface t) {
        this.scrollInterface = t;
    }

}

做完这些,如果还不放心,可以给子recycleview设置一个不可滚动的manager

public class NoSrcollLinearLayoutManager extends LinearLayoutManager {
    private boolean isScrollEnabled = true;//设置了一个可控变量,true为可滚动,false不可

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

    public void setScrollEnabled(boolean flag) {
        this.isScrollEnabled = flag;
    }

    @Override
    public boolean canScrollVertically() {
        //Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
        return isScrollEnabled && super.canScrollVertically();
    }
}

猜你喜欢

转载自blog.csdn.net/julystroy/article/details/86646877
今日推荐