android view的事件体系(四)

简言:

这篇博客主要讲的是滑动冲突问题,相信做过开发的都会知道,滑动冲突实在是太坑人了,只要出现滑动冲突,就会无法正常工作,产生滑动冲突主要是因为内外两层同时可以滑动,这个时候就会产生滑动冲突,今天主要讲解滑动冲突的解决方案:

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的事件体系(三):

https://blog.csdn.net/wk_beicai/article/details/89599305

发布了96 篇原创文章 · 获赞 370 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/wk_beicai/article/details/89633316