View的事件分发机制

点击事件用MotionEvent来表示,当一个点击操作发生时,事件最先传递给当前Activity,由Activity的dispatchTouchEvent来进行事件的分发,具体工作是由Activity内部的Window(也就是PhoneWindow)来完成的,window会讲事件传递给decorView,decorView是当前界面的底层容器(即 setContectView所设置的view的父容器),decorView调用ViewGroup的dispatchTouchEvent将事件分发到view(也就是setContectView所设置的view),当事件达到顶级View(一般是viewgroup)后会调用ViewGroup的dispatchTouchEvent,如果顶级ViewGroup拦截事件,即onInterceptTouchEvent方法返回true,则事件由ViewGroup处理,这时如果ViewGroup的mOnTouchListener被设置,则onTouch方法会被调用,否则onTouchEvent被调用,也就是说如果都提供onTouch会屏蔽掉onTouchEvent。如果顶级view不拦截事件,则会传递给他的子View,这时子View的dispatchTouchEvent方法会被调用,如果子View是ViewGroup,则事件传递过程跟顶级View一样,否则如果子View设置OnTouchListener被设置,则onTouch方法会被调用,否则onTouchEvent被调用,若都没有消费此事件最终将会传递给Activity处理。

注意

  • 同一事件序列是指从手指接触屏幕起,到手指离开屏幕这一过程中所产生的一系列事件,事件中有dowm,许多move和up

  • 正常情况下,一个事件序列只能被一个View拦截且消耗

  • 一旦某一元素拦截了事件,那么同一事件序列的所有事件都会直接交给他处理,并且它的onInterceptTouchEvent方法将不会再被调用,但是可通过强制手段将同一事件序列的事件分别由不同的view来同时处理,比如:一个view将本该自己处理的事件通过onTouchEvent强行传递给其他View

  • 事件传递总是由外向内的,子View可以通过requestDisallowInterceptTouchEvent来干扰父View的事件分发过程,但是ACTION_DOWN除外

  • activity:


    image.png
  • PhoneWindow:


    image.png
  • DecorView:


    image.png
  • ViewGroup:


    image.png

你可能感兴趣的:(View的事件分发机制)