- 1、事件对象MotionEvent主要有三个状态:action_down、action_move、action_up,
- 2、onInterceptTouchEvent中间有一次拦截即返回true,子view的事件就会拦截
- 3、当前View的onTouchEvent有一次不消费,后面都不会再走到当前View的onTouchEvent
- 4、子view可以控制viewGroup的onInterceptTouchEvent事件除actionDown事件以外,因为dispatchTouchEvent每次接收到ACTION_DOWN都会初始化状态,因此requestDisallowInterceptTouchEvent()方法不能影响ACTION_DOWN事件
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
} else {
// There are no touch targets and this action is not an initial down
// so this view group continues to intercept touches.
intercepted = true;
}
// 初始化FLAG_DISALLOW_INTERCEPT
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
cancelAndClearTouchTargets(ev);
resetTouchState();
}
- 5、OnTouchListener的优先级高于onTouchEvent(),onTouchListener事件也控制事件的消费,当onTouch()返回true,事件也被消费,而且不会调用onTouchEvent事件
- 6、如果view是disable的状态,但是clickable,LONG_CLICKABLE,CONTEXT_CLICKABLE,也会消费事件,但是不会motionEvent流程
- 7、onTouchEvent中如果有mTouchDelegate(view代理)的话,onTouchEvent会交给mTouchDelegate处理
- 8、onClickListener会在onTouchEvent事件的action_up事件之后调用
//分发事件伪代码
public boolean dispatchTouchEvent(MotionEnent ev){
boolean consume=false;
boolean intercepted=false;
if((action==MotionEvent.ACTION_DOWN||mFirstTouchTarget!=null)){
if((mGroupFlags&FlAG_DISALLOW_INTERCEPT)!=0){
intercepted=onInterceptTouchEvent(ev);
}else{
intercepted=false;
}
}
if(intercepted){
if(onTouchLiener!=null&&onTouchListener.onTouch()){
consume=true;
}else {
final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE
|| (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
|| (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;
onTouchEvent(ev)=if(disable){
return clickable
}else if(mTouchDelegate!=null){
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}else if(clickable || longClickable){
switch(ev){
case MotionEvent.ACTION_UP:
if(onClickeListener!=null){
performCLick();
}
break;
}
return true;
}
consume=onTouchEvent(ev);
}
}else{
consume=child.dispatchTouchEvent(ev);
}
return consume;
}