View的滑动冲突问题

View的滑动冲突问题

1. 滑动冲突出现的三种情况

 外部滑动方向和内部滑动方向不一致

 外部滑动方向和内部滑动方向一致

 上述两种情况的嵌套

但是这在使用ViewPager和listView的时候并不会出现滑动冲突的问题 那是因为ViewPager和listview已经替我们解决了滑动冲突的问题 但是如果是我们自己自定义的控件出现了问题 就没那么幸运了 因此我们还是要掌握滑动冲突的解决办法

2.滑动冲突的处理规则

滑动冲突虽然很烦人 但是它也不是很复杂 只要按照一定的处理规则就能解决  
像第一种情况我们通常可以通过判断滑动的方向来进行事件的分发  如果水平方向滑动就交给水平方向滑动的控件处理,如果竖直方向滑动,那么就交给竖直方向的控件处理  
对于第二种情况虽然无法根据滑动的角度判断交给哪个控件处理,但是它一定有既定的规则,我们只要按照这个规则来处理就可以了(不可能没有,如果没有如何判断哪个控件滑动呢?所以一定有)
对于第三种场景,类似与第二种  也要从业务上寻找分发事件的方式,虽然负责  但是一定可以实现  

3.滑动冲突的两种解决办法

外部拦截法:
   顾名思义,这个方法是在外部的控件中拦截事件 然后根据需要分发给控件的  
   伪代码如下:
@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        boolean intercept = false;
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                intercept = false;
                break;
            case MotionEvent.ACTION_MOVE:
                if(满足父控件的要求){//  满足要求就拦截事件
                    intercept = true;
                }else{
                    intercept = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                intercept = false;
                break;
        }
        return intercept;
    }
对于ACTION_DOWN 和 ACTION_UP 的intercept值的确定 是这个样子的   
想象一下  事件开始的时候总是先响应 ACTION_DOWN 事件  如果在这个事件中设置了 intercept值为true  即中断了事件 那么不论滑动方向是如何的 都会被父控件拦截(因为ACTION_DOWN是事件序列的开头)  下面的ACTION_MOVE的判断就丝毫没有了意义  所以必须返回false 进入ACTION_MOVE 中判断是否需要拦截   
ACTION_UP的道理也差不多  如果在ACTION_MOVE 中将事件交给了子控件处理  那么在ACTION_UP中 返回了true 又被父控件拦截了处理  也就是说子控件可能无法响应ACTION_UP事件  比如onclick方法  都可能无法响应  所以 这里要返回false  

内部拦截法:
   内部拦截法的意思是在子控件中处理拦截的逻辑  一般用的不是很多  外部拦截法使用比较多  但是这种方法也可以处理滑动冲突的问题  
   下面是伪代码:
@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                               getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                if(满足父控件的要求){//  满足要求就拦截事件
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return super.dispatchTouchEvent(ev);
    }

getParent().requestDisallowInterceptTouchEvent(false);这个方法 设置为true 表示父控件不拦截事件 false 表示父控件拦截事件
由于ACTION_DOWN事件不受这个的影响 所以不能让父控件拦截ACTION_DOWN事件 一旦拦截 那么所有的事件都不会传递到子控件中去 所以需要在父控件中 修改一下

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction()==MotionEvent.ACTION_DOWN){
            return false;
        }else{
            return super.onInterceptTouchEvent(ev);
        }

    }

这样就可以解决滑动冲突问题了。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值