View.invalidate()/requestLayout()內部核心點?

一般情況

invalidate()調用 只會導致draw()方法的調用,而measure()、layout() 則不會。
requestLayout()則相反,只會 調用measure()、layout(),而不會調用draw()。
總的來說,在這兩個函數上的區(qū)別很重要的一點就是:layoutRequested 是否為true.

原因:invalidate() 的時候, mLayoutRequested 變量不會被 設置為true。
requestLayout() , requestLayout如果沒有改變視圖大小,那就不會觸發(fā)onDraw,其根據layoutRequested為真,measureHierarchy會調用,即measure()調用,之后也就調用了layout()。

與invalidate()相關的兩個標志位

PFLAG_INVALIDATEDPFLAG_DRAWING_CACHE_VALID

invalidate()會不斷向上查找 ViewParent,直到ViewRootImpl,在這個向上的過程中,只有調用invalidate()方法的View才會將PFLAG_INVALIDATED標志置1,其他的View不會。而所有的View都是將PFLAG_DRAWING_CACHE_VALID置0。

在向下分發(fā)draw()的時候,又根據PFLAG_INVALIDATED 位是否為1 且PFLAG_DRAWING_CACHE_VALID位為0 的條件來確定View重繪。

想一想:既然這個過程是先向上查詢,再向下分發(fā)的過程,那為什么不直接對view繪制,而是這樣轉一圈?
我的理解是復用的scheduleTraversals()原因。而這個函數同樣是requestLayout()該當的核心方法。而requestLayout()則相對于調用的view來說,自己的視圖大小改變,必須會涉及到父控件的大小改變,那么就也會導致父View的重新measure、layout、draw()。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容