解决SwipeRefreshLayout嵌套ViewPager产生的滑动冲突的问题

解决滑动冲突主要有内部解决法和外部解决法,所以对于这个问题可以重写ViewPager的dispatchTouchEvent(MotionEvent ev)方法或者重写SwipeRefreshLayout的onInterceptTouchEvent(MotionEvent ev)根据逻辑判断事件消费给谁。我最先通过内部解决法重写ViewPager 发现没有效果,代码如下:

//重写ViewPager的 dispatchTouchEvent(MotionEvent ev)方法 ,这种方法无法解决!
   @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
               getParent().requestDisallowInterceptTouchEvent(false);
                isMove=false;
                lastX=ev.getRawX();
                lastY=ev.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                float gapX=lastX-ev.getRawX();
                float gapY=lastY-ev.getRawY();
                if(Math.abs(gapX)>mScaleTouchSlop||Math.abs(gapY)>mScaleTouchSlop){
                    isMove=true;
                }
                Logger.i("lx","gapx="+Math.abs(gapX)+"gapy="+Math.abs(gapY)+"isMove="+isMove);
                if(Math.abs(gapX)>Math.abs(gapY)){
                    getParent().requestDisallowInterceptTouchEvent(true);
                }else {
                    getParent().requestDisallowInterceptTouchEvent(false);
                }

                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
               getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

困扰了很久,在网上发现是SwipeRefreshLayout重写了requestDisallowInterceptTouchEvent方法导致无效的。

@Override
    public void requestDisallowInterceptTouchEvent(boolean b) {
        // if this is a List < L or another view that doesn't support nested
        // scrolling, ignore this request so that the vertical scroll event
        // isn't stolen
        if ((android.os.Build.VERSION.SDK_INT < 21 && mTarget instanceof AbsListView)
                || (mTarget != null && !ViewCompat.isNestedScrollingEnabled(mTarget))) {
            // Nope.
        } else {
            super.requestDisallowInterceptTouchEvent(b);
        }
    }

所以只能用外部解决法喽,解决思路和上面一样,就是当横向滑动的时候不要拦截事件直接给ViewPager去处理,其他情况交事件还是交给SwipeRefreshLayout自己判断处理。代码如下:

public class RefreshLayout extends SwipeRefreshLayout {

    private float startY;
    private float startX;
    // 判断viewPager是否在正在拖拽
    private boolean isviewPagerDragger;
    private  int mTouchSlop;
    public RefreshLayout(Context context) {
        super(context);
        init(context);
    }

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

    private void init(Context context){
        //滑动最小距离
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:

                startY = ev.getRawY();
                startX = ev.getRawX();
                // 初始化标记
                isviewPagerDragger = false;
                break;
            case MotionEvent.ACTION_MOVE:
                // 如果正在拖拽,直接返回flase,让viewPager处理
                if(isviewPagerDragger) {
                    return false;
                }

                float gapX = Math.abs(ev.getRawX() - startX);
                float gapY = Math.abs(ev.getRawY() - startY);
                // 如果是滑动并且是横向滑动,返回flase让viewPager处理
                if(gapX > mTouchSlop && gapX > gapY) {
                    isviewPagerDragger = true;
                    return false;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // 标记复位
                isviewPagerDragger = false;
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

}

嗯,上面就是解决SwipeRefreshLayout嵌套ViewPager产生的滑动冲突的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值