滑动冲突
场景一:外部滑动方向和内部滑动方向不一致
1.1场景
ViewPager + Fragment 配合使用所组成的页面滑动效果,实现左右滑动效果,里面通常嵌套一个 ListView ,这时 ViewPager 会自动处理这种滑动冲突。
若我们没有使用 ViewPager ,就要手动处理滑动冲突
外部上下滑动、内部左右滑动
1.2处理规则
根据滑动的方向来确定哪一层去拦截事件
根据滑动的坐标就能确定滑动方向:
- 滑动路径和水平方向的夹角
- 水平方向和竖直方向的距离差:竖直方向滑动的距离大就判断为竖直滑动
- 水平方向和竖直方向的速度差
1.3解决方法
1.31外部拦截法
外部拦截法是指所有的点击事件都要经过父容器的拦截处理。
需要重写父容器的 onInterceptTouchEvent 方法:
不拦截 ACTION_DOWN [ intercepted = false ],
不处理 ACTION_UP [ intercepted = false ] ,
处理 ACTION_MOVE 确定要不要拦截。
1.32内部拦截法
内部拦截法是指父容器不拦截任何事件,所有事件都传递给子元素,若子元素需要此事件就直接消耗掉,否则交给父容器进行处理。这种方法和 Android 中的事件分发机制不一致,需要配合 requestDisallowInterceptTouchEvent 方法才能正常工作。
需要重写子元素的 dispatchTouchEvent 方法:
ACTION_DOWN: [parent.requestDisallowInterceptTouchEvent(true)]
ACTION_MOVE: [如果父容器需要此类点击事件:parent.requestDisallowInterceptTouchEvent(false)]
重写父元素的 onInterceptTouchEvent :
if(action == ACTION_DOWN) {
...
return false;
}
else return true;
场景二:外部滑动方向和内部滑动方向一致
2.1场景
存在逻辑问题,系统无法知道用户在滑动哪一层
2.2处理规则
根据业务逻辑处理
场景三:上面两种情况的嵌套
3.1场景
场景一和场景二的嵌套,是几个单一滑动冲突的叠加
3.2处理规则
根据业务逻辑处理