Android(安卓)view 滑动事件冲突解决方法(理论篇)
16lz
2021-01-26
1.外部拦截法:
通过父容器拦截处理,如果父容器需要就拦截,如果父容器不需要就不拦截交给子view;主要是修改父容器的 onInterceptTouchEvent 方法,伪代码如下:
@Overridepublic 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; } break; } case MotionEvent.ACTION_UP: { intercepted = false; break; } } return intercepted;}
说明:
- ACTION_DOWN 这个事件里父容器必须返回 false,即不拦截ACTION_DOWN事件,因为一旦拦截了那么后续的 ACTION_MOVE、ACTION_UP都由父容器去处理,事件就无法传到子view了
- ACTION_MOVE 事件可以根据需要来进行拦截或者不拦截
- ACTION_UP 这个事件必须返回false
2.内部拦截法
内部拦截只父容器不拦截任何事件,所有事件都传给子view,如果子view需要则消耗掉事件,否则交给父容器处理;主要是修改子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);}
然后父容器需要做的改动如下:
@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这个标记的控制,所以一旦父容器拦截了ACTION_DOWN 事件那么所有的事件都无法传到子view中去了,这样内部拦截法就不起作用了;
更多相关文章
- Android(安卓)- TextView 实现部分文本点击事件
- ListView的Item中有CheckBox,导致OnItemClick不响应的解决办法
- 【安卓开发学习】6.ListView点击事…
- android事件之onInterceptTouchEvent,dispatchTouchEvent,onTouc
- android中scrollview与webview冲突事件
- Android(安卓)Studio 触摸屏事件
- arcgis for android 学习 - (4) 了解mapView的一些方法和事件
- Android触屏事件处理流程浅析
- Android:match_parent,fill_parent,wrap_content的区别