invalidate原理
1.view的invalidate会逐层找parent一直找到DecorView,DecorView是顶点了,但是DecorView还有个虚拟父view,ViewRootImpl。 ViewRootImpl不是一个View或者ViewGroup,他有个成员mView是DecorView,所有的操作从ViewRootImpl开始自上而下分发
2.view的invalidate不会导致ViewRootImpl的invalidate被调用,而是递归调用父view的invalidateChildInParent,直到ViewRootImpl的invalidateChildInParent,然后触发peformTraversals,会导致当前view被重绘,由于mLayoutRequested为false,不会导致onMeasure和onLayout被调用,而OnDraw会被调用
3.一个view的invalidate会导致本身PFLAG_INVALIDATED置1,导致本身以及父族viewgroup的PFLAG_DRAWING_CACHE_VALID置0
invalidate如果是个view,那就只有自己本身会draw,如果是ViewGroup就是对子view进行重绘
requestLayout原理
1.requestLayout会直接递归调用父窗口的requestLayout,直到ViewRootImpl,然后触发peformTraversals,由于mLayoutRequested为true,会导致onMeasure和onLayout被调用。不一定会触发OnDraw
2.requestLayout触发onDraw可能是因为在在layout过程中发现left,top,right,bottom和以前不一样,那就会触发一次invalidate,所以触发了onDraw,也可能是因为别的原因导致mDirty非空(比如在跑动画)
- requestLayout会导致自己以及父族view的PFLAG_FORCE_LAYOUT和PFLAG_INVALIDATED标志被设置。
view的requestLayout必然会导致该view和viewparent的重新measure,但不一定会导致子view的measure
最后,一般来说,只要刷新的时候就调用invalidate,需要重新measure就调用requestLayout,后面再跟个invalidate(为了保证重绘)
网友评论