文章目录
一.滑动冲突的原因
在界面中当有内外两层View同时可以滑动的时候,这个时候就会产生滑动冲突。
二.常见的冲突场景:
-
场景1
-
场景2
-
场景3
三.滑动冲突的处理规则
1.场景1的处理规则
对于场景1的处理规则是,当用户左右滑动时,需要让外部的View拦截点击事件,当用户上下滑动时,需要让内部的View拦截点击事件。具体来说就是根据他是水平滑动还是竖直滑动来确定到底是由谁来解决滑动冲突。
如何判断水平滑动还是竖直滑动:
- 依据滑动路径和水平方向所形成的夹角
- 依据水平方向和竖直水平的距离差,就是比较dx和dy的大小
- 依据水平方向和竖直方向的速度差,就是比较dx和dy方向的速度
- ……
2.场景2的处理规则
场景2比较特殊,他无法根据滑动的角度,距离差和速度差来判断,但他一般都能在业务上找到突破点。比如,业务规定,当处于某种状态时是,外部View响应,当处于另一种状态时,内部View响应。根据这个规则对滑动进行相应的处理。
3.场景3的处理规则
对于场景3来说,它的滑动规则更复杂,和场景2一样,它也无法根据滑动的角度,距离差和速度差来判断,同样只能通过业务上找到突破点。
四.滑动冲突的解决方法
针对滑动冲突,一般有两种解决方案,即内部拦截法和外部拦截法
1.外部拦截法
外部拦截法是指点击事件都先经过父容器处理,如果父容器需要此事件就拦截,如果不需要此事件就不拦截。这种方法比较符合点击事件的分发机制,外部拦截法需要重写父容器的OnInterceptTouchEvent方法,在内部做相应的拦截。
1.1模板代码:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = false;
int x = (int) ev.getX();
int y = (int) ev.getY();
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:{
intercepted = false;
break;
}
case MotionEvent.ACTION_MOVE:{
if(父容器需要当前点击事件){
intercepted = true;
}else {
intercepted = false;
}