Android处理ViewPager滑动冲突

本文可解决外部ViewPager和内部ViewPager左右滑动的冲突事件。
外层内层ViewPager都是左右滑动,不做处理,Android分不清到底是谁滑动,所以会出现滑动冲突。

首先我们先上完成效果图

演示

事件分发理解

那么该如何解决滑动冲突呢?

在此之前我们需要知道Android的事件分发机制。
在这里不追溯源码,只说结论,源码分析有时间在写。
事件分发由Activity->ViewGrop->View

上图理解:(网上大佬的图)
这是Android事件分发的整体流程
1

这里涉及到三个方法:

dispatchTouchEvent() //分发事件
oninterceptTouchEvent() //事件拦截 ViewGrop专有
ontouchEvent() //处理事件

在这里对三个方法进行简单分析:

**dispatchTouchEvent()**返回true表示事件被消费事件停止分发,逐层向上返回 后续事件会继续分发给到该view;返回false 表示 当前事件没有被消费 则事件回传给上层的ontouchevent()处理,返回super下发给子View。

onInterceptTouchEvent()****返回true表示当前的事件被ViewGroup拦截 则事件停止往下传递 ViewGroup自己处理事件,调用父类的super.dispatchTouchEvent(),最终执行自己的onTouchEvent();
返回false或者super 表示当前事件没有被ViewGroup拦截 则事件继续往下传递 事件传递到子view,调用view.dispatchTouchEvent()方法中去处理。

ontouchEvent()****返回true当前使用对象处理了当前事件,事件停止分发,逐层往dispatchTouchEvent()方法中去处理;返回false 当前使用的对象没有处理事件,将事件向上传给上层的onTouchEvent()处理。

回归题目,我们该如何解决滑动冲突呢

实现思路

我们只需要在重写内层ViewPager的OnTouchEvent()事件,自己处理自己的点击滑动事件即可,不是自己的都交由上层ViewPager处理。

代码如下:

public class CustomViewPage extends ViewPager {
    public CustomViewPage(@NonNull Context context) {
        super(context);
    }

    public CustomViewPage(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {      
        // 当拦截触摸事件到达此位置的时候,返回true,
        // 说明将onTouch拦截在此控件,进而执行此控件的onTouchEvent
        return true;
    }


    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        // TODO Auto-generated method stub
        // 每次进行onTouch事件都记录当前的按下的坐标
        switch (arg0.getAction()) {
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);//这句话是告诉父view,我的事件自己处理 不让父view拦截自己的事件
                break;
            case MotionEvent.ACTION_MOVE:
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(false);//这句话是告诉父view可以阻止我拦截我
                break;
        }


        return super.onTouchEvent(arg0);
    }

到这里就解决了。
同理处理ViewPager和ListView的滑动冲突也是同样的道理:重写ViewPager的OnInterceptTouchEvent()方法,判断滑动方向是否为左右,如果为左右则返回True,拦截交给父类执行自己的OntouchEvent()方法,否则下发给ListView。比较简单这里就不在演示了。

发布了7 篇原创文章 · 获赞 1 · 访问量 121

猜你喜欢

转载自blog.csdn.net/qq_35416214/article/details/105003635