View的滑动冲突处理

View的滑动冲突处理


1、滑动冲突的解决方式:

1.1外部拦截法:

所谓的外部拦截法是指点击事件都先经过父容器的拦截处理,如果父容器需要此事件就拦截,如果不需要此事件就不拦截,这样就可以解决滑动冲突的问题,这种方法比较符合点击事件的分发机制。外部拦截法需要重写父容器的onInterceptTouchEvent方法,在内部做相应的拦截即可。

外部拦截法的典型逻辑(伪代码)

private int mLastXIntercept = 0;        //分别记录上次滑动的坐标
private int mLastYIntercept = 0;

public boolean onInterceptTouchEvent(MotionEvent ev) {
    boolean intercepted = false;
    int x = (int) ev.getX();
    int y = (int) ev.getY();
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //这里必须是false,即不拦截ACTION_DOWN事件
            //因为一旦拦截后续的MOVE和UP事件都必须交由父容器处理,这时候事件就无法再传递给子元素了
            intercepted = false;
            break;
        case MotionEvent.ACTION_MOVE:
            int deltaX=x-mLastXIntercept;
            int deltaY=y-mLastYIntercept;
            //根须需要决定是否需要拦截
            if (如果父容器需要点击事件) {
                intercepted = true;
            } else {
                intercepted = false;
            }
            break;
        case MotionEvent.ACTION_UP:
            //这里必须返回false因为UP事件本身没有太多意义
            intercepted = false;
            break;
    }
    mLastXIntercept = x;
    mLastYIntercept = y;
    return intercepted;
}

1.2内部拦截法:

内部拦截法是指父容器不拦截任何事件,所有的事件都传递给志愿书,如果子元素需要此事件就直接消耗掉,否则就交由父容器进行处理,这种方法和Android中的事件分发机制不一致,需要配合requestDisallowInterceptTouchEvent方法才能正常工作,使用起来相比较外部拦截法稍显复杂。

内部拦截法的典型逻辑(伪代码)

1.重写子元素的dispatchTouchEvent方法

private int mLastX = 0;    //分别记录上次滑动的坐标
private int mLastY = 0;

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    int x = (int) ev.getX();
    int y = (int) ev.getY();
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            getParent().requestDisallowInterceptTouchEvent(true);
            break;
        case MotionEvent.ACTION_MOVE:
            int deltaX=x-mLastX;
            int deltaY=y-mLastY;
            //根须需要决定是否需要拦截
            if (如果父容器需要点击事件) {
                getParent().requestDisallowInterceptTouchEvent(false);
            } 
            break;
        case MotionEvent.ACTION_UP:
            //这里必须返回false因为UP事件本身没有太多意义
            break;
    }
    mLastX = x;
    mLastY = y;
    return super.dispatchTouchEvent(ev);
}

2.重写父元素的onInterceptTouchEvent方法

public boolean onInterceptTouchEvent(MotionEvent ev) {
    int action = ev.getAction();
    if(action = MotionEvent.ACTION_DOWN){
        return false;
    }else{
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值