View那些事兒(1) -- View繪製的整體流程

寫在開頭:Android的知識體系十分龐大,在Android的學習道路上難免會遇到學習了新東西就忘了舊東西的情況,本系列文章主要是對自己對View的學習過程進行一個深入的理解與總結,當然還結合自己在實際項目中的一些體會寫了一些東西。

當用戶打開你寫出的App的時候,第一眼關注到的是整個界面,而不是功能,所以要想吸引住用戶,就必須寫出一個好看的界面。好在Android提供了一套強大的繪圖體系,讓我們可以自由發揮,繪製出形形色色的View,從而構成豐富多彩的界面。不過要想掌握繪圖技巧,就必須掌握View的工作原理,我們就從View的最基本的原理開始探索吧。
先來看看一個窗口由那些部分組成的:
Android窗口的組成

接着解釋一下這些View的意義:

  • PhoneWindow:將Decoriew設置爲整個應用窗口的根View,是Window的實現類,它是Android中的最基本的窗口;
  • DecorView:又叫頂級View,系統會將要顯示的具體內容呈現在PhoneWindow上。一般情況下,它的內部會包含一個豎直方向的LinearLayout,在這個layout中有兩個部分:title和content,DecorView可以通過 View view = getWindow().getDecorView()獲得。它還是PhoneWindow與ViewRoot之間的橋樑,ViewRoot會通過DecorView設置窗口屬性;
  • DecorView中的TitleView:標題欄,一般指的是toolbar。
  • DecorView中的ContentView:內容欄,是一個id爲content的Framelayout,我們平時所寫的setContentView()其實就是在設置它。

上面提到了ViewRoot,那麼ViewRoot又是什麼呢?
我們要知道,View的繪製有三大流程:measure(測量)、layout(佈局)、draw(繪製),其中measure用來測量view的寬和高,layout用來確定view在父容器中位置,而draw則負責將view繪製在屏幕上。這裏的三大流程均是通過ViewRoot來完成的,ViewRoot的實現類是ViewRootImp。在ActivityThread中,當Activity對象被創建完畢後,會將DecorView添加到Window中,同時創建ViewRootImp對象,並將ViewRootImp和DecorView建立關聯,源碼中中片段如下:

root = new ViewRootImp(view.getContext(),display);
root.setView(view,wparams,panelParentView);

View的繪製流程是從ViewRoot的performTraversals()方法開始的,其過程如下圖所示:

performTraversals的工作流程

performTraversals()會依次調用performMeasure、performLayout和performDraw,這三個方法分別完成以上三大流程,例如performMeasure會調用measure方法,measure方法中又會調用onMeasure方法,在onMeasure方法中會對所有子view進行measure過程,子view再重複此過程,如此反覆就實現了view樹的遍歷。

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