Skip to content

Latest commit

 

History

History
80 lines (77 loc) · 3.2 KB

事件分发.md

File metadata and controls

80 lines (77 loc) · 3.2 KB

View事件分发

acatar

  • 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;
}