欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Android】完美解决SwipeRefreshLayout中嵌套ViewPager时滑动冲突的方法

程序员文章站 2022-06-08 18:10:49
...

一、解决思路:

    ①当ViewPager开始滑动时,将SwipeRefreshLayout的触发状态设置为不可用

    ②当ViewPager停止滑动时,将SwipeRefreshLayout的触发状态设置为可用

    ③当SwipeRefreshLayout被触发时,将ViewPager的触发状态设置为不可用

    ④当SwipeRefreshLayout触发结束时,将ViewPager的触发状态设置为可用

注:③和④我特意写出来,并标记划掉,因为这两步实际上是冗余的——
这是因为,我发现当SwipeRefreshLayout控件处于ViewPager控件的外层时,由于手势捕捉的优先级外层高于内层,所以外层控件(SwipeRefreshLayout)的手势触发事件是“肯定不会”被内层控件(ViewPager)“中途抢走”的。
而相反的,内层中的ViewPager的手势触发事件就可能会被外层的SwipeRefreshLayout“中途抢走”(也就是本博客讨论的滑动冲突问题)


二、不废话,直接上解决代码:

        
//添加页面滑动监听
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i1) {
            }

            @Override
            public void onPageSelected(int i) {
            }

            @Override
            public void onPageScrollStateChanged(int i) {
                if(i == 1) {
                    mSwipeRefreshLayout.setEnabled(false);//设置不可触发
                }else if(i == 2){
                    mSwipeRefreshLayout.setEnabled(true);//设置可触发
                }
            }
        });


三、代码解读:

①当i==1时,表示开始滑动,调用mSwipeRefreshLayout.setEnabled(false); //将SwipeRefreshLayout设置为不可触发

②当i==2时,表示结束滑动,调用mSwipeRefreshLayout.setEnabled(true); //将SwipeRefreshLayout设置为可触发


四、原理:

    注意OnPagerChangeListener.onPageScrollStateChanged(int i)方法,它是用来检测ViewPager的页面滑动状态改变的。

    这个方法的传入参数 i表示的是当前的滑动状态(注意是滑动状态,不是页码!!!我一开始差点被它这个默认的变量名所迷惑了……)
    它一共有3种滑动状态

        SCROLL_STATE_IDLE  ( 0     滑动终止

        SCROLL_STATE_DRAGGING   (1    滑动开始)

        SCROLL_STATE_SETTLING   (2    滑动结束)

    在每一次滑动事件中,三个值分别出现一次,且它们的出现顺序固定为 1 => 2 => 0 
    其中:2和0可以看作是一起出现的只是二者中间穿插了一个onPageSelected(int i)方法

    所以出现顺序也可以这么写: (N表示滑动页码)

        onPageScrollStateChanged(1) => onPageScrollStateChanged(2) + onPageSelected(N) + onPageScrollStateChanged(0)

    关于这个先后顺序,举个例子吧,模拟一次滑动事件如下:(注:->符号表示调用该方法,从上往下是调用顺序的先后)

        ①第一步:按下手指,开始滑动 ——
            listener -> onPageScrollStateChanged(1)

        ②第二步:松开手指,即结束滑动 ——
            listener -> onPageScrollStateChanged(2)
            listener -> onPageSelected(N) 

        ③滑动事件终止(自动)
           listener -> onPageScrollStateChanged(0)


五、后言:

    以上就是完美解决SwipeRefreshLayout中嵌套ViewPager时滑动冲突的方法和原理解释。

    博客写的不好,排版格式也没有太注意,如有问题,请务必指出,谢谢。