自定义View---怎么解决View的滑动冲突

来源:互联网 发布:海洋最深处 知乎 编辑:程序博客网 时间:2024/05/16 05:50

自定义View—怎么解决View的滑动冲突

常见View的滑动冲突有以下几种:
1.外部滑动和内部滑动方向不一样
2.外部滑动和内部滑动方向一样
3.以上两种情况的嵌套糅合

滑动冲突解决的规则:
1.根据自定义View的特征来解决滑动冲突。例如:外部滑动和内部滑动方向不一样时,我们可以通过滑动的水平方向上和垂直方向的距离来解决。
2.根据具体业务来解决滑动冲突。这种情况得具体问题具体分析。

  • 废话不多说,下面展示解决滑动冲突的两种方式,最后再通过两个例子来加深:

1.外部拦截法:所谓外部拦截法,指事件都先经过父容器的拦截处理方式。如果父容器需要此事件就拦截,反之~不拦截。外部拦截法需要重写父容器的onInterceptTouchEvent( … )方法,在此方法内部做相应的拦截处理,伪代码如下:

    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        boolean intercepter = false;        int x = (int) ev.getX();        int y = (int) ev.getY();        switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            intercepter = false;            // 其他处理            break;        case MotionEvent.ACTION_MOVE:            if (isSolve) {// 父容器需要拦截当前点击事件                intercepter = true;// 拦截事件            } else {                intercepter = false;            }            break;        case MotionEvent.ACTION_UP:            intercepter = false;//必须返回false,此事件ACTION_UP本身没有多大意义            break;        default:            break;        }        mLastXIntercept = x;        mLastYIntercept = y;        return intercepter;    }

2.内部吸收法:指父容器不拦截任何事件,所有事件都传递给子元素。如果子元素需要则接受,反之,传递给父容器来处理。此方法与Android的事件分发机制不一样。需要配合requestDissallowInterceptTouchEvent处理,使用起来相对来说有点复杂,伪代码如下:

    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        int x = (int) ev.getX();        int y = (int) ev.getY();        switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            parent.requestDisallowInterceptTouchEvent(true);//父容器不处理,parent必须为ViewGroup容器类型            break;        case MotionEvent.ACTION_MOVE:            int deltaX = x-mLastX;            int deltaY = y-mLastY;            if(!isSolve){//条件:父容器需要处理此类事件                parent.requestDisallowInterceptTouchEvent(false);//交给父容器处理            }            break;        case MotionEvent.ACTION_UP:            break;        default:            break;        }        mLastX = x;        mLastY = y;        return super.dispatchTouchEvent(ev);//返回的是父类的分发事件的值    }

除了子元素需要处理,父容器也需要做相应的处理,父容器需要默认拦截除ACTION_DOWN以外的其他事件,只有这样,当子元素调用parent.requestDisallowInterceptTouchEvent(false)方法时,父容器才能继续拦截所需要的事件,父容器处理伪代码如下:

    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        boolean intercepter = false;        int x = (int) ev.getX();        int y = (int) ev.getY();        switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            return false;            break;        case MotionEvent.ACTION_MOVE:            return true;            break;        case MotionEvent.ACTION_UP:            return true;            break;        default:            return true;        }    }

ok,伪代码分析完成,是不是很简单….此片博文时通过阅读任玉刚大神的《Android开发艺术探索》,加上自己的理解编写。具体例子将在下一篇展示。谢谢~

0 0
原创粉丝点击