简言:
这篇博客主要讲的是滑动冲突问题,相信做过开发的都会知道,滑动冲突实在是太坑人了,只要出现滑动冲突,就会无法正常工作,产生滑动冲突主要是因为内外两层同时可以滑动,这个时候就会产生滑动冲突,今天主要讲解滑动冲突的解决方案:
1)常见的滑动冲突场景:
1.外部滑动方向和内部滑动方向不一致
主要是将viewPager 和 fragment配合使用所组成的页面滑动效果,在这个效果中,可以通过左右滑动来切换页面。但是每个页面有可能又是一个listview,这种情况 就会出现滑动冲突(但是viewpager已经处理了滑动冲突)
2.外部滑动方向和内部滑动方向一致
这种情况稍微复杂一些。当内外两层都在同一个方向可以滑动的时候,这就存在逻辑问题,因为系统无法知道用户想让哪一层进行滑动,这样在手指滑动的时候就会出现问题;
3.上述两种情况的嵌套
场景一和场景二 进行嵌套,在许多应用中 就会有内层是场景一的滑动,外层是场景二的滑动。
2.滑动冲突的处理规则
场景一的处理规则:
当用户左右滑动时,需要让外部的view拦截点击事件,当用户上下滑动时,需要让内部view拦截点击事件,然后根据特性处理滑动冲突;
场景二的处理规则:
场景二比较特殊,无法根据滑动的角度,距离以及速度进行判断,但是可以通过业务上的逻辑找突破点,
当处于某种状态时需要外部view响应用户的滑动,处于另外一种状态则需要内部的view来响应view的滑动。
场景三的处理规则:
它的滑动规则更加复杂,同场景二一样,通过不同的业务逻辑进行处理:
3.滑动冲突的解决方式
1.外部拦截法
指点击事件都是经过父容器的拦截处理,如果父容器需要此事件就拦截,如果不需要此事件就不拦截,这样就解决了滑动冲突问题,这种方法符合点击事件的分发机制,
外部拦截需要重写父容器的onInterceptTouchEvent方法。在内部做相应的拦截即可 ,下面是伪代码:
这个是外部拦截法的典型逻辑,针对不同的滑动冲突,只需要修改父容器需要当前事件的这个条件即可,
2)内部拦截法
内部拦截法是指父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就直接消费掉,否则就交给父容器处理,需要requestDisallowInterceptTouchEvent方法才能正常工作,比外部拦截比较复杂,伪代码如下:
上面代码是典型的内部拦截,面对不同的滑动策略需要修改里面条件即可,
注: 上述代码为什么不能拦截ACTION_DOWN 事件?
通过上面代码可以看出,ACTION_DOWN 事件并不受FLAG_DISALLOW_INTERCEPT这个标志位控制,
所以一旦父容器拦截ACTION_DOWN事件,事件无法传递到子元素中,造成内部拦截无法起作用;
下面是关于滑动事件的案例:
(其中包含内部拦截法,外部拦截法, 同向滑动问题的案例等)
csdn下载:
https://download.csdn.net/download/wk_beicai/11148972
android view的事件体系(三):