Android:梳理自定義View工作流程

目錄

1. 儲備知識

1.1 ViewRoot

  • 定義
    連接器,對應於ViewRootImpl

  • 作用

    1. 連接WindowManagerDecorView
    2. 完成View的三大流程: measurelayoutdraw
  • 特別注意

// 在主線程中,Activity對象被創建後:
// 1. 自動將DecorView添加到Window中 & 創建ViewRootImpll對象
root = new ViewRootImpl(view.getContent(),display);

// 3. 將ViewRootImpll對象與DecorView建立關聯
root.setView(view,wparams,panelParentView)

1.2 DecorView

  • 定義:頂層View

Android 視圖樹的根節點;同時也是 FrameLayout 的子類

  • 作用:顯示 & 加載佈局

View層的事件都先經過DecorView,再傳遞到View

  • 特別說明
    內含1個豎直方向的LinearLayout,分爲2部分:上 = 標題欄(titlebar)、下 = 內容欄(content)

示意圖

Activity中通過 setContentView()所設置的佈局文件其實是被加到內容欄之中的,成爲其唯一子View = id爲content的FrameLayout

// 在代碼中可通過content得到對應加載的佈局

// 1. 得到content
ViewGroup content = (ViewGroup)findViewById(android.R.id.content);
// 2. 得到設置的View
ViewGroup rootView = (ViewGroup) content.getChildAt(0);

1.3 Window、Activity、DecorView 與 ViewRoot的關係

  • 簡介

示意圖

1.4 自定義View基礎

瞭解自定義View流程前,需瞭解一定的自定義View基礎,具體請看文章:(1)自定義View基礎 - 最易懂的自定義View原理系列


2. 繪製準備

  • 回憶上圖,可看出最後1步 = 繪製

     

    示意圖

  • 但在繪製前,系統會有一些繪製準備,即前面幾個步驟:創建PhoneWindow類、DecorView類、ViewRootmpl類等

故,下面我會先將繪製前的準備,再開始講繪製流程


3. 繪製流程概述

  • 從上可知,View的繪製流程開始於:ViewRootImpl對象的performTraversals()
  • 源碼分析
/**
  * 源碼分析:ViewRootImpl.performTraversals()
  */
  private void performTraversals() {

        // 1. 執行measure流程
        // 內部會調用performMeasure()
        measureHierarchy(host, lp, res,desiredWindowWidth, desiredWindowHeight);

        // 2. 執行layout流程
        performLayout(lp, mWidth, mHeight);

        // 3. 執行draw流程
        performDraw();
    }
  • 從上面的performTraversals()可知:View的繪製流程從頂級View(DecorView)ViewGroup開始,一層一層從ViewGroup至子View遍歷測繪

即:自上而下遍歷、由父視圖到子視圖、每一個 ViewGroup 負責測繪它所有的子視圖,而最底層的 View 會負責測繪自身

示意圖

  • 繪製的流程 = measure過程、layout過程、draw過程,具體如下

示意圖

示意圖

下面,我將詳細講解View繪製的三大流程:measure過程、layout過程、draw過程


4. 詳細介紹

4.1 Measure 過程

  • 作用
    測量View的寬 / 高
  1. 在某些情況下,需要多次測量(measure)才能確定View最終的寬/高;
  2. 該情況下,measure過程後得到的寬 / 高可能不準確;
  3. 此處建議:在layout過程中onLayout()去獲取最終的寬 / 高
  • 具體流程

示意圖

示意圖

4.2 Layout過程

  • 作用
    計算視圖(View)的位置

即計算View的四個頂點位置:LeftTopRightBottom

  • 具體流程

     

    示意圖

示意圖

  • 詳細講解

請看文章:自定義View Layout過程 - 最易懂的自定義View原理系列(3)

4.3 Draw過程

  • 作用
    繪製View視圖

  • 具體流程

示意圖

示意圖

至此,關於自定義View的工作流程講解完畢。


5. 自定義View的步驟

步驟1:實現Measure、Layout、Draw流程

  • 從View的工作流程(measure過程、layout過程、draw過程)來看,若要實現自定義View,根據自定義View的種類不同(單一View / ViewGroup),需自定義實現不同的方法
  • 主要是:onMeasure()onLayout()onDraw(),具體如下

示意圖

步驟2:自定義屬性

  1. 在values目錄下創建自定義屬性的xml文件
  2. 在自定義View的構造方法中加載自定義XML文件 & 解析屬性值
  3. 在佈局文件中使用自定義屬性

6. 實例講解

結合原理 & 實現步驟,若需實現1個自定義View,請看文章:手把手教你寫一個完整的自定義View

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章