Android 從0開始自定義控制元件之 ViewRoot 與 DecorView (五)
轉載請標明出處: http://blog.csdn.net/airsaid/article/details/53525335
本文出自:周遊的部落格
前言
好幾個星期沒寫部落格了,今天繼續來學習 View 相關的知識:View 的三大流程:測量流程、佈局流程、繪製流程。
在瞭解這三大流程之前,首先來了解下 View 的幾個基本概念,關於 ViewRoot 和 DecorView。
ViewRoot
VIewRoot 光看名字,貌似是 ViewTree 的根節點?其實萬萬不是, ViewRoot 或者說對應的 ViewRootImlp 類,它其實是連線 WindowManger 和 DecorView 的橋樑。View 的三大流程都是通過 ViewRoot 來完成的。
在 ActivityThread 中,當 Activity 物件被建立完畢後,會將 DecorView 新增到 Window 中,同時會建立 ViewRootImpl 物件,並將 ViewRootImpl 物件與 DecorView 進行關聯。
整個 View 的繪製流程,是從 ViewRoot 的 performTraversals 方法開始的。
它經過了 measure、layout、draw 這三個過程才最終將一個 View 繪製出來,其中 measure 是用於測量 View 的寬高的,layout 是用於當繼承 ViewGroup 時確定子 View 位置的, draw 則是負責將 View 繪製在螢幕上。
performTraversals 會依次呼叫 performMeasure、performLayout、performDraw 這三個方法,這三個方法會依次完成頂級 View 的 measure、layout、draw 三大流程。
其中 performMeasure 方法會接著呼叫 measure 方法,在 measure 方法中又會去呼叫 onMeasure 方法。在 onMeasure 方法中對所有的子元素進行了 measure 過程 ,這個時候 measure 流程就從父容器傳遞到子元素中了,這樣就完成了一次 measure 過程。接著,子元素又重複了一遍 measure 過程,如此反覆,直到沒有了子元素。這樣就完成了整個 View 樹的遍歷。
其中 layout 和 draw 的流程同上,兩者同樣都有 performLayout 、performDraw 和 layout、draw 方法,唯一不同的是,performDraw 的傳遞是在 draw 方法中通過 dispatchDraw 來實現的,不過這並沒有什麼本質上的區別。
稍作整理一下,其中各流程各決定了 View 的如下方面:
measure 過程決定了 View 的寬/高。完成以後,可以通過 getMeasureWidth 和 getMeasureHeight 來獲取 View 測量後的寬/高。
layout 過程決定了 View 四個定點的座標和實際 View 的寬/高。完成以後,可以通過 getTop、getLeft、getBottom、getRight 來獲取 View 的四個頂點的位置,並可以通過 getWidth 和 getHeight 方法獲取 View 的最終寬/高。
- draw 過程決定了 View 的顯示,只有當 draw 方法完成以後,View 才能夠顯示到螢幕上。
DecorView
DecorView 繼承自 FrameLayout,是一個 ViewGroup。在整個 ViewTree 中, DecorView 是整個 ViewTree 的頂層 View。View 的所有事件,都先經過 DecorView,然後再傳遞給 View。
DecorView 在一般情況下,內部會包含一個豎直的 LInearLayout,裡面有上下兩部分,上面是標題欄,下面是內容,內容佈局有一個預設的 id: content。
我們在 Activity 中 通過 setContentView() 方法設定的佈局,其實就是新增到了內容部分裡。如果我們想獲取到內容佈局的話,可以通過如下方法獲取:
ViewGroup content = (ViewGroup) findViewById(android.R.id.content);
想獲取到我們設定的 View 的話,可以通過如下方式獲取:
View childAt = content.getChildAt(0);
參考
《Android 開發藝術探索》
相關文章
- 自定義控制元件(一) Activity的構成(PhoneWindow、DecorView)控制元件View
- Android自定義控制元件之自定義組合控制元件Android控制元件
- Android自定義控制元件之自定義屬性Android控制元件
- Android自定義組合控制元件之自定義屬性Android控制元件
- Android自定義控制元件——自定義屬性Android控制元件
- Android自定義View——從零開始實現雪花飄落效果AndroidView
- Android開發之自定義隨機驗證碼控制元件Android隨機控制元件
- 從Android到ReactNative開發(三、自定義原生控制元件支援)AndroidReact控制元件
- 從 0 到 1Android 自定義 View(三)畫圖的五個元素元件AndroidView元件
- Android自定義控制元件之自定義ViewGroup實現標籤雲Android控制元件View
- android自定義開關控制元件-SlideSwitchAndroid控制元件IDE
- Android開發自定義View之滑動按鈕與自定義屬性AndroidView
- Android自定義控制元件之基本原理Android控制元件
- Android自定義控制元件系列之基礎篇Android控制元件
- Android 控制元件架構與自定義控制元件詳解Android控制元件架構
- Android自定義View——從零開始實現水波浪進度框AndroidView
- Android自定義View——從零開始實現覆蓋翻頁效果AndroidView
- Android自定義View——從零開始實現圓形進度條AndroidView
- 從 Android 到 React Native 開發(三、自定義原生控制元件支援)AndroidReact Native控制元件
- Flutter 之 自定義控制元件Flutter控制元件
- android:建立自定義控制元件Android控制元件
- Android開發之自定義SpinnerAndroid
- (Android自定義控制元件)Android自定義狀態提示圖表Android控制元件
- Android自定義View——從零開始實現書籍翻頁效果(二)AndroidView
- Android自定義View——從零開始實現書籍翻頁效果(四)AndroidView
- Android自定義View——從零開始實現書籍翻頁效果(三)AndroidView
- Android自定義View——從零開始實現書籍翻頁效果(一)AndroidView
- 【組合控制元件】android自定義控制元件之帶文字的ImageView控制元件AndroidView
- 【Android】自定義樹形控制元件Android控制元件
- Android開發之自定義View(一)AndroidView
- Android開發之自定義View(二)AndroidView
- android 自定義控制元件 自定義屬性詳細介紹Android控制元件
- Android自定義View——從零開始實現可展開收起的水平選單欄AndroidView
- Android自定義View——從零開始實現可暫停的旋轉動畫效果AndroidView動畫
- 從 0 到 1Android 自定義 View(四)貝塞爾曲線AndroidView
- 從 0 開始瞭解 DockerDocker
- 從 0 開始學架構架構
- Android自定義View——從零開始實現書籍翻頁效果(效能優化篇)AndroidView優化