Android DrawerLayout 和ViewPager滑动冲突解决

最近遇到项目整体是Activity搭配DrawerLayout的抽屉样式,在左侧抽屉的顶部,有一个ViewPager无限轮播。

并要求ViewPager左滑下一页右滑上一页3秒自动轮播下一页点击按住停止轮播

同时DrawerLayout的NavigationMenuView左滑打开右滑关闭

滑动事件同时存在,手指滑动头部区域ViewPager响应,滑动其他区域DrawerLayout打开or关闭。

    

这必然存在滑动冲突。

网上有很多例子,但是都无法完全符合需求设定。

有些是在DrawerLayout打开后,锁定滑动关闭功能,此时DrawerLayout不再接受点击滑动事件,onTouch就必然传递到ViewPager了,等ViewPager滑动到最后一页,在打开滑动关闭功能,此时就滑动关闭了。

这种适用于ViewPager不能无限轮播,和ViewPager占据整个DrawerLayout等抽屉区域。


解决思路:

这是因为点击滑动事件被DrawerLayout消费掉了,如果想让ViewPager接受点击滑动事件,就必须将onTouch传递到ViewPager。

解决方案:

自定义DrawerLayout,重载onInterceptTouchEvent方法。

public class EBDrawerLayout extends DrawerLayout {

    public EBDrawerLayout(Context context) {
        this(context, null);
    }

    public EBDrawerLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public EBDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_MOVE){
            if (ev.getY() > 10 && ev.getY() < 300)
                return false;
        }
        return super.onInterceptTouchEvent(ev);
    }
}


public class LoopViewPager extends RelativeLayout {
    private static final int MESSAGE_LOOP = 5;
    @BindView(R.id.vp_loop_pager) ViewPager loopViewPager;

    private int loop_ms = 2000;
    private Context mContext;
    private LoopPagerAdapter loopPagerAdapter;
    private List<BannerInfo> bannerInfos;//banner data
    private OnBannerItemClickListener onBannerItemClickListener = null;

    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);
            if (msg.what == MESSAGE_LOOP) {
                if (loopViewPager.getCurrentItem() < Short.MAX_VALUE - 1) {
                    loopViewPager.setCurrentItem(loopViewPager.getCurrentItem() + 1, true);
                    sendEmptyMessageDelayed(MESSAGE_LOOP, loop_ms);
                }
            }
        }
    };

    public LoopViewPager(Context context) {
        this(context, null);
    }

    public LoopViewPager(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoopViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        this.setClickable(true);
        this.mContext = context;

        initializeView();
    }

    private void initializeView() {
        View mView = View.inflate(mContext, R.layout.custom_loop_viewpager, this);
        ButterKnife.bind(this, mView);

        loopViewPager.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_MOVE:
                        stopLoop();
                        break;
                    case MotionEvent.ACTION_UP:
                        startLoop();
                        break;
                    default:
                        break;
                }
                return false;
            }
        });
    }

    public void updateLoopData(List<BannerInfo> datas) {
        if (datas != null && datas.size() > 0) {
            this.bannerInfos = datas;
        }
        loopPagerAdapter = new LoopPagerAdapter(getContext(), bannerInfos, onBannerItemClickListener);
        loopViewPager.setAdapter(loopPagerAdapter);

        int index = Short.MAX_VALUE / 2 - (Short.MAX_VALUE / 2) % bannerInfos.size();
        loopViewPager.setCurrentItem(index);
    }

    public void setLoop_ms(int loop_ms) {
        this.loop_ms = loop_ms;
    }


    public interface OnBannerItemClickListener {
        void onBannerClick(int index, List<BannerInfo> banner);
    }

    public void setOnBannerItemClickListener(OnBannerItemClickListener onBannerItemClickListener) {
        this.onBannerItemClickListener = onBannerItemClickListener;
    }

    public void startLoop() {
        handler.removeCallbacksAndMessages(MESSAGE_LOOP);
        handler.sendEmptyMessageDelayed(MESSAGE_LOOP, loop_ms);
    }

    public void stopLoop() {
        handler.removeMessages(MESSAGE_LOOP);
    }

}








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值