标签:
本文根据任玉刚的博客和书以及http://blog.csdn.net/guolin_blog/article/details/9097463整理简单好学习。
处理对象:点击事件
处理问题:解决滑动冲突、焦点抢占
处理办法:1.使失效:让onTouchEvent不消耗事件clickable和longclickable都为false,enable不影响返回值
2.在父视图分发的时候就将onInterceptEvent设置为false,不再继续分发事件
处理事件会用到的三个方法:
step1==diapatchTouchEvent(MotionEvent ev)--事件分发
Step2==onInterceptTouchEvent(Event ev)-boolean-拦截事件(默认false)
Step3==onTouchEvent(Event ev)--bolean-是否消耗当前事件
简单梳理一下结论:结论:
1. Android事件分发是先传递到ViewGroup,再由ViewGroup传递到View的。
2. 在ViewGroup中可以通过onInterceptTouchEvent方法对事件传递进行拦截,onInterceptTouchEvent方法返回true代表不允许事件继续向子View传递,返回false代表不对事件进行拦截,默认返回false。
3. 子View中如果将传递的事件消费掉,ViewGroup中将无法接收到任何事件。
先连看看点击事件的处理流程图:
下面来说几个细节:
1Touch事件的处理过程 事件序列Down》move》move》move》。。。》up
2点击事件传递过程 Activity》Window》全局VIew》子view
3只能被一个点击事件拦截且消耗,拦截必处理,默认不拦截,
4在注册监听的时候都要重写方法,即被调用onTouchListener==onTouch被调用》》
onClickListener==onClick被调用
附dispatchEvent的源码:
public boolean dispatchTouchEvent(MotionEvent event) {
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}
从源码中可以看出,这两个方法都是在View的dispatchTouchEvent中调用的,onTouch优先于onTouchEvent执行。如果在onTouch方法中通过返回true将事件消费掉,onTouchEvent将不会再执行。
关于事件会执行2遍的问题网上那个有解答
不管点击还是触屏都有按下弹起这两个事件的,onTouch会捕获ACTION_DOWN和ACTION_UP这两个动作,所以执行了两次。同理:onkey、dispatchTouchEvent、dispatchKeyEvent。要想执行一次,可加判断ACTION_DOWN和ACTION_UP这两个动作.
具体戳连接
http://www.xuebuyuan.com/1467240.html
处理滑动冲突
处理规则:根据距离差来判断
处理方法:外部拦截法==重写父布局viewGroup的拦截onInterceptTouchEvent方法处理拦截
外部拦截法说明:
down-n个move》即up是最后处理的事件
Action_down与Action_up必须返回false,move看具体情况而定
标签:
原文地址:http://blog.csdn.net/russe124/article/details/51331488