Android View的事件分发机制和滑动冲突
View的事件分发机制
说白了,就是一个点击事件的传递,从手指触碰到屏幕那一刻开始到手指离开屏幕结束。
由一个MotionEvent.ACTION_DOWN
事件,若干个MotionEvent.ACTION_MOVE
事件,一个MotionEvent.ACTION_UP
事件构成。
涉及到的重要方法有:
boolean dispatchTouchEcent(MotionEvent ev) //用来分派event:只要事件传递到了当前View,那么该方法就一定会被调用。返回结果表示是否消耗当前事件。
boolean onInterceptTouchEvent(MotionEvent event)//用来拦截event:该方法是在dispatchTouchEcent方法内部调用的,可以用来判断是否拦截某个事件。如果当前View拦截了某个事件,那么在这同一个事件序列中,此方法不会再次被调用。返回结果表示是否拦截当前事件。
boolean onTouchEvent(MotionEvent event)//用来处理event:该方法也是在dispatchTouchEcent方法内部调用的,用来处理事件。返回结果表示是否处理当前事件,如果不处理,那么在同一个事件序列里面,当前View无法再收到后续的事件。
现在来说明下这三个方法之间的关系,这里需要区分为ViewGroup与View
ViewGroup:
public boolean dispatchTouchEvent(MotionEvent ev){
if(onInterceptTouchEvent(ev)){
return onTouchEvent(ev);
}else{
return child.dispatchTouchEvent(ev);
}
}
View:
public boolean dispatchTouchEvent(MotionEvent ev){
return onTouchEvent(ev);
}
onTouch,OnClick关系
他们的调用优先级依次是onTouch>OnClick
这里要说的一点是,OnClick是在onTouch的MotionEvent.ACTION_UP
之后才会被调用到,假设我们在MotionEvent.ACTION_UP
的时候return true
那么OnClick事件就不会执行,所以如果你同时监听了Touch与OnClick事件,可以用MotionEvent.ACTION_UP
的时候return true
的方式来截断事件的传递。
我的另外一篇文章中就有使用到:自定义View仿iOS的UiSwitch控件
既然已经了解了View的事件分发机制,那么滑动冲突应该也就能迎刃而解了吧。这里就不在叙述了,可参考陈添的这篇文章。