解决滑动冲突
Posted dfqin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决滑动冲突相关的知识,希望对你有一定的参考价值。
ScrollView中的View是可以点击的,但是又能拖动滑动,可以推测首先事件是传递到子View的,但是滑动事件被ScrollView拦截了,翻看源码可以证实此推测
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged))
return true;
........
所以如果在ScrollView中再嵌套一个子ScrollView,当滑动的时候时候,MOVE事件被外层ScrollView拦截了,所以里层ScrollView的内容不会滑动,这种就是常见的滑动冲突。
常见的处理方式方式有外部拦截法和内部拦截法
1. 外部拦截法,就是事件都先经外部容器拦截处理,如果外部容器不需要此事件,就不拦截。像一个垂直滑动的容器内嵌套了一个水平滑动的容器。外部容器判断滑动的角度来决定是水平滑动还是垂直滑动,然后决定是外部容器拦截处理还是传递给子View处理。
2.内部拦截法,就是事件交给内部处理,如果内部不处理,再交给父容器处理。有些场景父容器并不知道此事件是否该子View处理还是自己处理,例如两个垂直滑动的ScrollView嵌套,外部容器并不知道滑动事件该自己处理还是该子View处理,但是子View知道事件该由谁处理,所以事件交由子View处理,子View不处理的再交由父View。通常需要子View调用parent.requestDisallowInterceptTouchEvent(true),明确不让父View拦截事件。
下面是一个ScrollView嵌套处理的例子:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
super.onLayout(changed, l, t, r, b);
maxY = getChildAt(0).getMeasuredHeight() - getHeight();
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
switch (ev.getAction())
case MotionEvent.ACTION_DOWN:
getParent().getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if (getScrollY() > 0 && getScrollY() < maxY)
getParent().requestDisallowInterceptTouchEvent(true);
else
getParent().requestDisallowInterceptTouchEvent(false);
break;
case MotionEvent.ACTION_UP:
getParent().getParent().requestDisallowInterceptTouchEvent(false);
break;
return super.dispatchTouchEvent(ev);
以上是关于解决滑动冲突的主要内容,如果未能解决你的问题,请参考以下文章
解决RcyclerView嵌套EditText时,产生的焦点冲突,导致RecyclerView自动滑动问题