Android依我见之滑动冲突处理

来源:互联网 发布:各国人工智能发展现状 编辑:程序博客网 时间:2024/05/20 20:18

在Android的开发过程中,相信各位开发看官都或多或少接触或使用过,也是学习Android开发过程中的一大难点,相信不少人也有此体会,看了不少相关的各类文章,感觉还是似懂非懂,当然可能当你看完本文,可能还是似懂非懂,本文只是小菜在学习解决滑动冲突过程中自己的一点点小小的心得,固记录之。

在阅读《Android开发艺术探索》一书过程中,该书作者较详细的阐述为什么会产生滑动冲突以及如何去解决?第一个问题为什么会产生滑动冲突其实最根本的原因就在与外部View与内部View都能滑动,如外部View可以横向滑动,内部View竖向滑动;或者外部View与内部View都可以在同一个方向滑动等;总之只要外部View与内部View都可以滑动,只要我们不处理好就会造成滑动冲突,造成可能我们不想要的结果;当然有滑动冲突问题,就有解决办法,该书作者提出了一般处理滑动冲突问题的固定套路,个人还是挺认同的,但是其中也有一些问题可能作者没有说明清楚又或者自己以偏概全导致了一些问题,本人最后都会一一的说明出来,当然也仅仅代表个人的一些想法。

针对外部View可以横向滑动,内部View竖向滑动或者外部View竖向滑动,内部View横向滑动,滑动冲突解决的套路就是:当用户水平滑动时,让横向滑动的View拦截事件,当用户竖直滑动时让竖向滑动的View拦截;那如何确定用户到底是水平滑动还是竖直滑动呢?当然最直接的办法就是根据滑动过中两个点之间的坐标计算出水平方向滑动的距离以及竖直方向滑动的距离,当水平方向滑动的距离大就认定为水平方向滑动,反之当竖直方向滑动的距离大就认定为竖直方向滑动,当然这只是一种办法,至于怎么样算水平滑动,什么样算竖直滑动,判断的方法也许不一样,但是最终我们通过到底水平滑动还是竖直滑动处理此类滑动冲动问题;其中该书作者又提出了外部拦截法内部拦截法去具体解决,本人在此只贴出外部拦截法的使用过程,至于内部拦截法,可以阅读《Android开发艺术探索》一书具体章节进行查阅。所谓外部拦截法就是在外部View的onInterceptTouchEvent方法中进行拦截,在此贴出一段该书中的伪代码:

public boolean onInterceptTouchEvent(MotionEvent event) {        boolean intercept = false ;        switch(event.getAction()){            case MotionEvent.ACTION_DOWN :                intercept = false ; //Down事件不能进行拦截,拦截后该手势之后一系列事件都将由本View的                                    //onTouchEvent处理,子View无法接收到                 break ;            case MotionEvent.ACTION_MOVE:                if(需要拦截当前事件){                   intercept = true ;                }else{                   intercept = false ;                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                intercept = false ;                break;        }        return intercept;    }

上述代码就是外部拦截法的典型逻辑,引用该书中的一段言论:

针对不同的滑动冲突,只需要修改父容器需要拦截当前事件这个条件即可,其他均不需做修改并且也不能修改,在onInterceptTouchEvent方法中,首先是ACTION_DOWN这个事件,父容器绝大部分情况下必须返回false,即不拦截ACTION_DOWN事件,这是因为一旦父容器拦截了ACTION_DOWN,那么后续的ACTION_MOVE和ACTION_UP事件都会直接交给父容器处理,这个时候事件没法再传递给子元素了;其次是ACTION_MOVE事件,这个事件可以根据需要来决定是否拦截,如果父容器需要拦截就返回true,否则返回false;最后是ACTION_UP事件,这里必须要返回false,因为ACTION_UP事件本身没有太多意义。

上述言论说明了外部拦截法需要注意的一些地方,如不太理解,请阅读相关事件分发机制相关的文章。

针对外部View与内部View同一个方向滑动的冲突套路其实跟上面不同方向滑动的处理逻辑是一个道理的,也分为外部拦截法内部拦截法,当然这里也只说外部拦截法:也是在外部View的onInterceptTouchEvent方法中进行拦截,只是外部View与内部View都是同一个方向滑动,不能像之前处理水平和竖直滑动距离去判断外部View是否进行拦截,只是拦截需要的是外部View与内部View之间的零界点去判断,可能这样说很抽象,举个例子,外部View为ScrollView,内部View为ListView,它们都是在竖直方向进行滑动,那我们如何判定此时应该滑动的是ScrollView还是ListView呢?前面说的零界点其实就是:当ListView在顶部(第一个可见item=0)或者在底部(最后一个可见item=数量-1)的时候,这个时候应该由ScrollView处理滑动事件,否则由ListView处理滑动事件。

0 0
原创粉丝点击