ScrollView 嵌套 RecyclerView 滑动冲突相关问题,BAT 这种大厂履历意味着什么
break;}}return intercepted;}
ACTION_DOWN 这个事件里父容器必须返回 false,即不拦截 ACTION_DOWN 事件,因为一旦拦截了那么后续的 ACTION_MOVE、ACTION_UP 都由父容器去处理,事件就无法传到子 view 了
ACTION_MOVE 事件可以根据需要来进行拦截或者不拦截
ACTION_UP 这个事件必须返回 false,就会导致子 View 无法接受到 UP 事件,这个时候子元素中的
onClick()
事件就无法处触发。
2.内部拦截法
父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则就交由父容器进行处理。这种方法需要配合requestDisallowInterceptTouchEvent()
方法才能正常工作。
主要是修改子 view 的dispatchTouchEvent()
方法
@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {int x = (int) ev.getX();int y = (int) ev.getY();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN: {getParent().requestDisallowInterceptTouchEvent(true);break;}case MotionEvent.ACTION_MOVE: {if (父容器需要此类事件) {getParent().requestDisallowInterceptTouchEvent(false);}break;}case MotionEvent.ACTION_UP: {break;}}return super.dispatchTouchEvent(ev);}
父容器需要重写onInterceptTouchEvent()
方法
@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {int action = ev.getAction();if(action == MotionEvent.ACTION_DOWN){return false;}else {return true;}}
父容器拦截 ACTION_DOWN 以外的其他事件,因为 ACTION_DOWN 事件不受 FLAG_DISALLOW_INTERCEPT 这个标记的控制,所以**一旦父容器拦截了 A
CTION_DOWN 事件那么所有的事件都无法传到子 view 中去了**,这样内部拦截法就不起作用了。
四、问题解决
下面就来实际解决本文中遇到的滑动冲突问题。通过上述分析可知,本文所遇到的问题通过外部拦截法,重写 ScrollView 的onInterceptTouchEvent()
方法即可快速简单的解决。
public class FScrollView extends ScrollView {private float mLastXIntercept = 0f;private float mLastYIntercept = 0f;
public FScrollView(Context context, AttributeSet attrs) {super(context, attrs);}
@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {boolean intercepted = false;float x = ev.getX();float y = ev.getY();int action = ev.getAction() & MotionEvent.ACTION_MASK;switch (action) {case MotionEvent.ACTION_DOWN: {intercepted = false;//初始化 mActivePointerIdsuper.onInterceptTouchEvent(ev);break;}case MotionEvent.ACTION_MOVE: {//横坐标位移增量 float deltaX = x - mLastXIntercept;//纵坐标位移增量 float deltaY = y - mLastYIntercept;if (Math.abs(deltaX) < Math.abs(deltaY)) {intercepted = true;} else {intercepted = false;}break;}case MotionEvent.ACTION_UP: {intercepted = false;break;}}mLastXIntercept = x;mLastYIntercept = y;return intercepted;}
评论