invalidate原理
1.view的invalidate會逐層找parent一直找到DecorView,DecorView是頂點了,但是DecorView還有個虛擬父view,ViewRootImpl。 ViewRootImpl不是一個View或者ViewGroup,他有個成員mView是DecorView,所有的操作從ViewRootImpl開始自上而下分發(fā)
2.view的invalidate不會導致ViewRootImpl的invalidate被調(diào)用,而是遞歸調(diào)用父view的invalidateChildInParent,直到ViewRootImpl的invalidateChildInParent,然后觸發(fā)peformTraversals,會導致當前view被重繪,由于mLayoutRequested為false,不會導致onMeasure和onLayout被調(diào)用,而OnDraw會被調(diào)用
3.一個view的invalidate會導致本身PFLAG_INVALIDATED置1,導致本身以及父族viewgroup的PFLAG_DRAWING_CACHE_VALID置0
invalidate如果是個view,那就只有自己本身會draw,如果是ViewGroup就是對子view進行重繪
requestLayout原理
1.requestLayout會直接遞歸調(diào)用父窗口的requestLayout,直到ViewRootImpl,然后觸發(fā)peformTraversals,由于mLayoutRequested為true,會導致onMeasure和onLayout被調(diào)用。不一定會觸發(fā)OnDraw
2.requestLayout觸發(fā)onDraw可能是因為在在layout過程中發(fā)現(xiàn)left,top,right,bottom和以前不一樣,那就會觸發(fā)一次invalidate,所以觸發(fā)了onDraw,也可能是因為別的原因?qū)е耺Dirty非空(比如在跑動畫)
- requestLayout會導致自己以及父族view的PFLAG_FORCE_LAYOUT和PFLAG_INVALIDATED標志被設置。
view的requestLayout必然會導致該view和viewparent的重新measure,但不一定會導致子view的measure
最后,一般來說,只要刷新的時候就調(diào)用invalidate,需要重新measure就調(diào)用requestLayout,后面再跟個invalidate(為了保證重繪)