一、requestLayout和invalidate區(qū)別
1、requestLayout會(huì)直接遞歸調(diào)用父窗口的requestLayout,直到ViewRootImpl,然后觸發(fā)peformTraversals,由于mLayoutRequested為true,會(huì)導(dǎo)致onMeasure和onLayout被調(diào)用。不一定會(huì)觸發(fā)OnDraw 。
2、requestLayout觸發(fā)onDraw可能是因?yàn)樵谠趌ayout過程中發(fā)現(xiàn)l,t,r,b和以前不一樣,那就會(huì)觸發(fā)一次invalidate,所以觸發(fā)了onDraw,也可能是因?yàn)閯e的原因?qū)е耺Dirty非空(比如在跑動(dòng)畫) 。
3、view的invalidate不會(huì)導(dǎo)致ViewRootImpl的invalidate被調(diào)用,而是遞歸調(diào)用父view的invalidateChildInParent,直到ViewRootImpl的invalidateChildInParent,然后觸發(fā)peformTraversals,會(huì)導(dǎo)致當(dāng)前view被重繪,由于mLayoutRequested為false,不會(huì)導(dǎo)致onMeasure和onLayout被調(diào)用,而OnDraw會(huì)被調(diào)用。
延伸閱讀:
二、View繪制的三個(gè)步驟
View繪制分三個(gè)步驟,順序是:onMeasure,onLayout,onDraw。經(jīng)代碼親測(cè),log輸出顯示:調(diào)用invalidate方法只會(huì)執(zhí)行onDraw方法;調(diào)用requestLayout方法只會(huì)執(zhí)行onMeasure方法和onLayout方法,并不會(huì)執(zhí)行onDraw方法。
所以當(dāng)我們進(jìn)行View更新時(shí),若僅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方法。