標籤:android 布局 layout
在學習自訂群組件的時候,偶然發現官網的這篇文章,覺得不錯,於是試著翻譯出來。一是為了和大家分享,二是為了加深自己的印象。水平有限,翻譯過程中有不正確的地方,歡迎指正。
原文地址為: How Android Draws Views
當一個Activity呈現在使用者面前時,其布局將被繪製出來。android系統將處理繪製的過程,但是,前提是Activity需要提供其布局的根節點。
繪製過程從布局的根節點開始,然後對整個布局樹型結構(layout tree)進行測量並繪製,繪製過程沿著布局樹型結構(layout tree)進行,依次渲染其中的各個View。在這個遍曆過程中,遇到ViewGroup時,每個ViewGroup(注意,ViewGroup也屬於View的一種)將依次繪製包含於其中的View;遇到View時,View將繪製自身。由於繪製的過程是沿著布局樹型結構(layout tree)遍曆的,所以,布局樹型結構(layout tree)中的父節點將先於孩子結點被繪製,而兄弟結點則按照它們出現的順序進行繪製。
繪製布局需要經過兩個pass process(傳遞過程?),分別是measure pass和layout pass(可以翻譯為測量的傳遞過程,計算布局的傳遞過程?)。measure pass是在方法measure(int,int) 中進行的,measure pass自上而下地遞迴遍曆布局結構。在遞迴過程中,每個View都沿著布局樹傳遞dimension specifications,在measure pass結束時,每個View都將獲得自身的測量結果。第二個pass process是layout pass,這個過程在在layout(int,int,int,int) 中進行,並且和measure pass一樣是自上而下的(top-down),在layout pass過程中,每個父結點都將利用measure pass的測量結果,計算出各個子結點的位置。
當一個View對象的measure()方法執行完之後,該View以及其子結點的getMeasureWidth()和getMeasureHeight()的返回值必須已經被賦值,(其實這兩個方法分別返回View對象中的變數mMeasureWidth和mMeasureHeigth,這兩個變數的注釋是:Height/Width as measured during measure pass)。各個View的測量寬度和測量高度必須遵從其父結點傳遞過來的限制條件(其實就是上文提到的dimension specifications)。這樣才能保證在measure pass結束時,每個父節點能接受其各個子結點的測量結果。一個parent View可能不止觸發其子結點的measure()方法依次,比如,父結點可能第一次首先測量每個沒指定大小的子結點,測量出它們需要佔用多大的空間,而如果經過第一輪測量,各個子結點的計算結果相互之間有所衝突,則父結點將再次調用各個子結點的onMeasure()方法測量各個子結點。
measure pass使用兩個類去傳遞關於測量大小的值。這兩個類分別是ViewGroup.LayoutParams和MeasureSpec。View對象可以藉助ViewGroup.LayoutParams對象去告訴它的父結點,它需要怎樣的大小和放置在什麼位置。最基礎的ViewGroup.LayoutParams類只能描述View的高和寬。它可以指定的高和寬有以下三類
- 某個確切的數值
- MATH_PARENT,代表該View希望和它的父結點一樣大(減去padding)
- WRAP_CONTENT,代表該View希望大小足夠包圍住它的內容(加上padding)
ViewGroup.LayoutParams有幾個子類,它們分別為ViewGroup幾個對應的子類而存在。比如,RelativeLayout有自己的一個ViewGroup.LayoutParams的子類,它有一個特殊的功能,可以講子結點設定在水平方向上的中點,或者垂直方向上的中點。
MeasureSpec對象是由父結點傳遞給子節點的一個對象,父結點對子結點的限制資訊儲存在該對象中。MeasureSpec對象可以有以下三種模式:
- UNSPECIFIED:父結點對子結點的大小沒有任何要求。
- EXACTLY: 父結點要求其子節點的大小指定為某個確切的值。其子節點以及其他子孫結點都需要適應該大小。
- AT MOST:父結點要求其子節點的大小不能超過某個最大值,其子節點以及其他子孫結點的大小都需要小於這個值
該文章中還提到兩個小tips:
- invalidate():調用該方法,可以強制重新繪製介面
- requestLayout():當前布局大小改變時,可以調用該方法,重新整理布局。
Android介面繪製流程--------How Android Draws Views