合理的佈局能夠在提高效能的同時,簡化邏輯的複雜度。
目標
在滿足需求的情況下,使用最少的層次結構來構建佈局,同時避免在過度重繪模式下出現粉紅色和紅色。
方法
佈局優化的方式有很多,下面我們進行一一介紹:
刪除不必要的背景
對於一款APP而言,UI通常會給出一個UI標準,其中包括頁面預設背景,進入/退出動畫等,所以我們可以在主題中設定Activity的背景,這樣可避免在佈局檔案中設定背景。
PS:當然,將主題的背景設定為透明,在佈局檔案中設定背景也可較少重繪次數,但是這種方案在低端機上可能出現頁面切換時可看到桌面的情況。
減少佈局的層次結構
多使用RelativeLayout。雖然LinearLayout比較好用,但是侷限性也比較大,實現複雜的佈局需要巢狀多層結構才可實現。所以對於非線性的佈局,都推薦使用RelativeLayout來實現,同時應儘可能避免RelativeLayout的巢狀。
使用RelativeLayout的時候需要注意,由於元素之間採用的是相對位置,所以作為被依賴的元素,一定不能在程式碼中使用GONE來隱藏處理,而應該使用不常用的INVISIBLE來實現隱藏。INVISIBLE與GONE的區別是INVISIBLE雖然隱藏了,但依然佔據空間。
當然,還有更強大的佈局容器——ConstraintLayout, 這是Google 2016年I/O大會上提出的一個可靈活控制子View的位置和大小的容器,可以說集LinearLayout和RelativeLayout的優點於一身,使用一層結構也可實現複雜的佈局,真正做到了扁平化。這也是Google推薦的佈局容器,Android Studio2.3之後建立的佈局預設容器就是它。具體的使用可參考:ConstraintLayout使用指南
簡化動畫
在APP的開發中,為了提高使用者的體驗,UI通常會要求新增一些動畫,但是有些動畫需要多層佈局來實現。這時可和UI協商是否可簡化動畫,以減少佈局層次。在需要動畫的佈局中使用FrameLayout是一個不錯的選擇,畢竟Material Design的核心就是層次化的佈局結構。
match_parent與wrap_content:
在寫佈局檔案時,有些情況下match_parent與wrap_content都可實現需求,這時可優先使用match_parent,熟悉View的measure就會知道,match_parent的實現邏輯比wrap_content要簡單很多。
使用< merge >標籤
使用標籤合併佈局。有幾點需要注意:
-
標籤必須是根節點,否則會丟擲InflateException異常;
-
所代替的標籤不需要設定padding,backgound,gravity等屬性,否則合併後無法實現相應的需求;
-
代替的標籤和包含的標籤應相同,否則佈局合併後將會顯示異常。比如標籤代替的是LinearLayout,那麼include這個佈局的也應該為LinearLayout,這樣佈局才能正常顯示。
main.xml
<LinearLayout ...>
<include layout="@layout/item_layout">
</LinearLayout>
複製程式碼
item_layout.xml
<LinearLayout ...>
<TextView ...>
<TextView ...>
</LinearLayout>
複製程式碼
此時可使用標籤對佈局進行簡化:
<merge>
<TextView ...>
<TextView ...>
</merge>
複製程式碼
使用標籤
使用ViewStub延遲載入佈局。在開發過程中,有些佈局需要在點選時才出現,這時就可採用ViewStub來延遲載入,以提高佈局的渲染速度。
使用標籤
標籤只是用於佈局複用,從而簡化佈局的視覺效果,方便後期維護,對於效能方面幾乎沒什麼影響。所以這個標籤只是提一下,複用佈局時可使用。
建議
-
編寫佈局檔案時多思考,選擇合適的Layout進行佈局,以儘可能減少佈局層次;
-
多使用Lint工具進行檢查,Lint工具可對佈局提出很多中肯的建議,包括多餘的層次,硬編碼等;
-
佈局寫好之後開啟開發者模式下的“顯示過渡重繪區域”開關,檢查佈局的重繪情況,以便於進一步的優化;
-
使用Hierarchy分析佈局結構。Android Studio->Tools->Android->Android Device Monitor->Window->Open Perspective->選擇Hierarchy View確定即可開啟Hierarchy視窗。需要注意的是:Hierarchy只能在開發版的手機上使用。
總結
靈活使用上面提到的幾種優化方式,在開發過程中,基本上所有的佈局都可在顯示過渡重繪區域的情況下避免出現紅色,甚至是粉紅色。