ViewGroup是个抽象类,具体实现都是在其自类中实现,此处主要是来分析一下Touch事件的分发机制。
Touch事件分发是一个自上而下的过程,本质上为一次DFS深度遍历,大致的顺序为由Activity --> ViewGroup --> View。
最先由Activity捕获然后进行分发;然后判断当前的View是否为ViewGroup,如果是ViewGroup则由ViewGroup再次进行分发,遍历其所有的各个子View。
ViewGroup分发前需要调用onInterceprtTouchEvent函数,该函数用来捕获TouchEvent,默认返回false,如果返回true,则该TouchEvent已被消费,结束分发,可以用来屏蔽子View的TouchEvent等。
ViewGroup本身并不会响应TouchEvent,只是起到一个遍历的作用,如果子View不是ViewGroup的时候,则调用View的分发机制。如果TouchEvent没有被消费,则前往兄弟节点或父节点。
View的分发机制中,优先View.onTouchListener.onTouch()函数,其次再响应View.onTouchEvent()函数。
当遍历完所有View,TouchEvent还没被消费完时,最后调用Activity.onTouchEvent(),无论此处是否有响应,整个分发就到此结束了。
以下从源码角度进行以下分析
Acitivity
事件最先由DecorView进行响应,然后回调Activity的dispatchTouchEvent函数,onUserInteraction函数主要用于协助操作状态栏等,可以先无视,getWindow函数获取的是PhoneWindow的对象,通过Window分发到下层的View。
遍历完整个View,TouchEven还没有被消费时,才会调用Activity的onTouchEvent函数。
这个函数相当于分发的起点和终点。
PhoneWindow
PhoneWindow是Window的子类,调用基类的dispatchTouchEvent函数,此处基类即为ViewGroup。
ViewGroup
ViewGroup中的事件分发比较复杂,有很多过滤,清空的逻辑,所以我们主要看下关键的几段代码。
此处为父View拦截TouchEvent的onInterceptTouchEvent函数,如果要禁止父View的拦截,子View可以在OnTouchEvent中调用getParent().requestDisallowInterceptTouchEvent(true)函数来禁止onInterceptTouchEvent函数的调用。
网友评论