多层嵌套ViewPager 解决冲突问题

我们在项目中很多得时候会用到Activity+ViewPager+Fragment作为主框架,然后在其中一个Fragment中得列表中 添加一个Banner作为广告位,但是这样 容易有焦点冲突得问题

 

其实很关键地方在我们内部得那个BannerViewPager 这里需要对拦截器 进行编写

public class BannerViewPager extends ViewPager {
    private float downX, downY;
    public BannerViewPager(@NonNull Context context) {
        super(context);
    }

    public BannerViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        boolean intercept = super.onInterceptTouchEvent(e);
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = e.getX();
                downY = e.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                // 只要横向大于竖向,就拦截掉事件。
                // 部分机型点击事件(slopx==slopy==0),会触发MOVE事件。
                // 所以要加判断(slopX > 0 || sloy > 0)
                float horizon=e.getX() - downX;

                float slopX = Math.abs(e.getX() - downX);
                float slopY = Math.abs(e.getY() - downY);
                //  Log.log("slopX=" + slopX + ", slopY="  + slopY);
                if((slopX > 0 || slopY > 0) && slopX >= slopY){
                    int currentIndex=getCurrentItem();
                    int size=this.getAdapter().getCount();
                    if (currentIndex==0){
                        if (horizon>0){//向左滑动
                            requestDisallowInterceptTouchEvent(true);
                            intercept = true;
                        }
                    }
                    if (currentIndex==size-1){
                        if (horizon<0){//向右滑动
                            requestDisallowInterceptTouchEvent(true);
                            intercept = true;
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                intercept = false;
                break;
        }

        return intercept;
    }
}

 

因为事件传递的规则,如果我们需要拦截某个焦点  那么就要从写onInterceptTouchEvent方法

由于我们只是拦截其中某个条件下的事件,所以我们必须先调用super方法

boolean intercept = super.onInterceptTouchEvent(e);

如果我们想拦截某个事件,那么在onInterceptTouchEvent的返回值 必须位true

为了不影响父view不对我们处理进行拦截,所以调用

requestDisallowInterceptTouchEvent(true);

进行请求设置。

 

然后事件交给我们BannerViewPager进行处理

否则的话 事件就会一直传递下去。

我在代码里面设置了这样的逻辑:

                    int currentIndex=getCurrentItem();
                    int size=this.getAdapter().getCount();
                    if (currentIndex==0){
                        if (horizon>0){//向左滑动
                            requestDisallowInterceptTouchEvent(true);
                            intercept = true;
                        }
                    }
                    if (currentIndex==size-1){
                        if (horizon<0){//向右滑动
                            requestDisallowInterceptTouchEvent(true);
                            intercept = true;
                        }
                    }

这个是为了增加约束条件,在ViewPager第一个和最后一个页面的时候,不能再向两边滑动了,只能向内滑动。

 

还有一点需要注意,必须在BannerViewPager的适配器中的view添加点击事件

不然这个点击焦点 都没有view去消费掉,那么就会传递到最外层的ViewPager的onTouchEvent方法里面,那我们的拦截就没有意义了

参考的事件分发文章:https://www.jianshu.com/p/e99b5e8bd67b

这是我自己总结的事件分发的文章:https://blog.csdn.net/huazai30000/article/details/85316082

源码地址:https://github.com/xuhuawei131/BannerViewPagerDemo

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值