一、requestLayout和invalidate區(qū)別
1、requestLayout會直接遞歸調(diào)用父窗口的requestLayout,直到ViewRootImpl,然后觸發(fā)peformTraversals,由于mLayoutRequested為true,會導致onMeasure和onLayout被調(diào)用。不一定會觸發(fā)OnDraw 。
2、requestLayout觸發(fā)onDraw可能是因為在在layout過程中發(fā)現(xiàn)l,t,r,b和以前不一樣,那就會觸發(fā)一次invalidate,所以觸發(fā)了onDraw,也可能是因為別的原因?qū)е耺Dirty非空(比如在跑動畫) 。
3、view的invalidate不會導致ViewRootImpl的invalidate被調(diào)用,而是遞歸調(diào)用父view的invalidateChildInParent,直到ViewRootImpl的invalidateChildInParent,然后觸發(fā)peformTraversals,會導致當前view被重繪,由于mLayoutRequested為false,不會導致onMeasure和onLayout被調(diào)用,而OnDraw會被調(diào)用。
延伸閱讀:
二、View繪制的三個步驟
View繪制分三個步驟,順序是:onMeasure,onLayout,onDraw。經(jīng)代碼親測,log輸出顯示:調(diào)用invalidate方法只會執(zhí)行onDraw方法;調(diào)用requestLayout方法只會執(zhí)行onMeasure方法和onLayout方法,并不會執(zhí)行onDraw方法。
所以當我們進行View更新時,若僅View的顯示內(nèi)容發(fā)生改變且新顯示內(nèi)容不影響View的大小、位置,則只需調(diào)用invalidate方法;若View寬高、位置發(fā)生改變且顯示內(nèi)容不變,只需調(diào)用requestLayout方法;若兩者均發(fā)生改變,則需調(diào)用兩者,按照View的繪制流程,推薦先調(diào)用requestLayout方法再調(diào)用invalidate方法。