CoordinatorLayout+ViewPager+RecyclerView滑动冲突问题。

我以前也没太关注过这个问题,今天浏览网站看到有人反映,于是我创建布局测了一下。
构建好布局之后:发现上划的时候可能会和ViewPager侧滑会产生冲突,导致滑动卡顿。
通过事件分发我们知道流程是CoordinatorLayout(可拦截)→ViewPager(可拦截)→RecyclerView(消费)→ViewPager(消费)→CoordinatorLayout(消费)
所以我们Tounch消费作用在RecyclerView上;然后通过控制ViewPager的是否能侧滑解决:
开始操作:
第一步:重写ViewPager,加上可控侧滑方法:

public class MyViewPager extends ViewPager {
private boolean isScroll = true;//true可滑动 false不可滑动
public MyViewPager(Context context) {
    super(context);
}

public MyViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (isScroll) {
        return super.onTouchEvent(ev);//消费
    } else {
        return false; //不消费所以不可滑动
    }
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (isScroll) {
        return super.onInterceptTouchEvent(ev);
    } else {
        return false;//不拦截,可以达到子控件
    }
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    return super.dispatchTouchEvent(ev);
}

public void setIsScroll(boolean isScroll) {   //实例设置是否禁用滑动方法
    this.isScroll = isScroll;
}

}

第二步,在RecyclerView的滑动监听上做操作:

Float startX;//初始X位置
Float startY;//初始Y位置
Float moveX;//滑动后X
Float moveY;//滑动后Y
boolean isSelectTouch = false;//记录滑动是否确定,不管我们判断RecyclerView消费滑动还是ViewPager滑动消费,都是确定了,不在滑动中改变策略,知道手指抬起或者下一次按下时重新判断.
private void init() {
    rv.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = event.getX();
                    startY = event.getY();
                    Log.i("iiiiiiiiiiiiiiiii", "down");
                    MainActivity.vp.setIsScroll(false);//点击设置不可滑动,因为我发现View侧滑后会消费掉,所以摁下先禁用
                    isSelectTouch = false;//解除上一次策略
                    break;
                case MotionEvent.ACTION_MOVE:
                    moveX = event.getX();
                    moveY = event.getY();
                    if (isSelectTouch == false) {
                        Log.i("iiiiiiiiiiiiiiiii", "move");
                        if (Math.abs(moveY - startY) > Math.abs(moveX - startX)) {
                            MainActivity.vp.setIsScroll(false);
                            isSelectTouch = true;//已定策略,执行RecyclerView上下滑动
                        } else if (Math.abs(moveX - startX) > Math.abs(moveY - startY)) {
                            MainActivity.vp.setIsScroll(true);
                            isSelectTouch = true;//已定策略,执行ViewPager左右滑动
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    Log.i("iiiiiiiiiiiiiiiii", "up");
                    MainActivity.vp.setIsScroll(true);//打开ViewPager滑动
                    isSelectTouch = false;//解除上一次策略
                    break;
            }
            return false;
        }
    });
}

好了这就比较顺滑。结束…

ps:我发现RecyclerView上下划并丢出的时候,本身items会冲一部分。像人有主流控件如:喜马拉雅就没有此问题。
猜想,如果解决此问题,也是要彻底禁用和开启RecyclerView滑动的,但是如果禁用之后就不会自动顶CoordinatorLayout布局了,可以通过滑动改变Y之,然后改变AppBarLayout的位置,总之来说这样CoordinatorLayout布局就完全成了鸡肋,所以判断这种主流App控件是完全自定义布局,根本不需要CoordinatorLayout+TabLayout。可以用ScrollView+头部+MyTabLayout(可自定义)+RecyclerView,这样全自定义还可控滑动速度,好处比谷歌的design框架要好,写起来比较麻烦,后期有时间再写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值