Android中View的滑动冲突及其解决方式

什么是滑动冲突

当界面中两层都可以滑动的时候,由于系统不知道滑动该什么适合交给什么控件来处理,往往就达不到预想的效果。

典型的场景就是在ViewPager中加入ListView,此时,滑动冲突就出现了,要不就是内部无法滑动,要不就是外部无法滑动,否则就是两者都没法动了。

常见的滑动冲突场景类型

滑动冲突主要有三个场景

1.场景1——外部内部滑动方向不一致
2.场景2——外部和内部滑动方向一致
3.场景3——场景1和场景2的混合体

具体如下图:
2016-03-10 20-23-48屏幕截图

处理滑动冲突的原则

处理滑动冲突,可以通过分情况控制事件的分发来达到目的

对于场景1,我们可以通过检测手势滑动的方向来判断把事件交给哪层处理, 判断方向可以通过滑动的距离或者夹角来判断。

对于场景2,由于方向相同,所以要根据业务状态来判断交给哪个View处理滑动

对于场景3,同样是要根据业务状态来处理

具体的处理方法

对于场景1,按照处理原则,又有两种处理法

1.外部拦截法
1.1 外层容器的onInterceptTouchEvent(MotionEvent event)方法中对于 ACTION_DOWN事件返回false,因为一旦拦截ACTION_DOWN,后续事件就不能传给子控件了
1.2 对于ACTION_MOVE事件,可以根据我们的处理原则来判断是否返回true进行拦截
1.3 对于ACTION_UP事件,也要返回FALSE,否则子控件无法判断事件序列结束,也就无法调用onClick方法了

2.内部拦截法
2.1 内部容器中进行处理,但是需要配合requestDisallowInterceptTouchEvent方法才能工作,重写其onInterceptTouchEvent方法,但是如果子View不处理的话,调用parent.requestDisallowInterceptTouchEvent(false)即可交还给父控件处理。
2.2 父控件依然不能拦截ACTION_DOWN事件,不然整个事件都无法再传给子控件。

对于场景2,3,方法与1相似,不过要根据业务状态来判断。

网络上有很多如何处理冲突的具体例子,这里就不赘述了。

u3coding

A software developer

Leave a Comment

Your email address will not be published. Required fields are marked *

*