Android 滑动冲突处理
2016-03-15 10:38
344 查看
要想解决滑动冲突就必须好好理解 Android 的事件分发机制。不了解 Android 事件分发机制的请先参考资料学习一下。
一般有 2 种方法
1 外部拦截法
这个非常简单,因为事件是从父 view 向子 view 进行分发的,所以我们可以重写父控件的 onInterceptTouchEvent, 如果父容器需要某个事件就拦截,如果不需要就不拦截交给子view处理。
伪代码如下
这里有一点需要注意,父容器不能拦截 ACTION_DOWN 事件,因为父容器一旦拦截了 ACTION_DOWN 事件那么后面所有的事件就都由它来处理了,子 view 就接收不到任何事件了。
2 内部拦截法
父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则交给父容器就行处理,需要配合 requestDisallowInterceptTouchEvent 来干预父容器对事件的拦截。
伪代码如下
一要重写子view的 dispatchTouchEvent
二要重写父容器的 onInterceptTouchEvent 让父容器默认拦截除 ACTION_DOWN 以外的所有事件
内部拦截法不太好理解,比较饶。
外部拦截法与事件分发机制流程一致,简单好理解,所以一般情况下都会优先选择外部拦截法。
一般有 2 种方法
1 外部拦截法
这个非常简单,因为事件是从父 view 向子 view 进行分发的,所以我们可以重写父控件的 onInterceptTouchEvent, 如果父容器需要某个事件就拦截,如果不需要就不拦截交给子view处理。
伪代码如下
public boolean onInterceptTouchEvent(MotionEvent event) { boolean intercept = false; int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: intercept = false; break; case MotionEvent.ACTION_MOVE: if (父容器需要这个事件) { intercept = true; } else { intercept = false; } break; case MotionEvent.ACTION_UP: intercept = false; break; } mLastX = x; mLastY = y; return intercept; }
这里有一点需要注意,父容器不能拦截 ACTION_DOWN 事件,因为父容器一旦拦截了 ACTION_DOWN 事件那么后面所有的事件就都由它来处理了,子 view 就接收不到任何事件了。
2 内部拦截法
父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则交给父容器就行处理,需要配合 requestDisallowInterceptTouchEvent 来干预父容器对事件的拦截。
伪代码如下
一要重写子view的 dispatchTouchEvent
public boolean dispatchTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: parent.requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: int deltaX = x - mLastX; int deltaY = y - mLastY; if (父容器需要这个事件) { parent.requestDisallowInterceptTouchEvent(false); } break; } mLastX = x; mLastY = y; return super.dispatchTouchEvent(event); // 干预之后再扔给父容器 }
二要重写父容器的 onInterceptTouchEvent 让父容器默认拦截除 ACTION_DOWN 以外的所有事件
public boolean onInterceptTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { return false; } else { return true; } }
内部拦截法不太好理解,比较饶。
外部拦截法与事件分发机制流程一致,简单好理解,所以一般情况下都会优先选择外部拦截法。
相关文章推荐
- Android之AsyncTask的使用
- Android volley 解析(四)之缓存篇
- android系统如何调用自带的相机相册
- Service Manager在Android进程间通信机制Binder中的身份--守护进程
- Android volley 解析(三)之文件上传篇
- 从源码的角度理解四大组件的工作过程——Android开发艺术探索笔记
- android:configChanges="orientation" 不起作用
- Android EditTexit设置最大长度 中文按2个字符计算
- android软件服务器的一些想法
- Android Volley解析(二)之表单提交篇
- Android开发性能优化大总结
- android listview用adapter.notifyDataSetChanged()无法刷新每项的图标
- Android Volley解析(一)之GET、POST请求篇
- Android 生成文字图片验证码
- android-cts兼容性自动化测试
- Systemv 和Posix的主要功能和定义
- Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()
- java.lang.NoSuchFieldError: android.support.v7.appcompat
- Android中R.java丢失不见的解决方案
- android广播和service的那些小事