Android佈局優化利器include和ViewStub
當建立複雜的佈局的時候,有時候會發現新增了很多的ViewGroup和View。隨之而來的問題是View樹的層次越來越深,應用也變的越來越慢,因為UI渲染是非常耗時的。
這時候就應該進行佈局優化了。這裡介紹兩種方式,分別為<include>標籤和ViewStub類。
<include/>
使用<include/>是為了避免程式碼的重複。設想一種情況,我們需要為app中的每個檢視都新增一個footer,這個footer是一個顯示app名字的TextView。通常多個Activity對應多個XML佈局檔案,難道要把這個TextView複製到每個XML中嗎?如果TextView需要做修改,那麼每個XML佈局檔案都要進行修改,那簡直是噩夢。
物件導向程式設計的其中一個思想就是程式碼的複用,那麼怎麼進行佈局的複用呢?這時,<include/>就起作用了。
如果學過C語言,那麼對#include應該不陌生,它是一個預編譯指令,在程式編譯成二進位制檔案之前,會把#include的內容拷貝到#include的位置。
Android中的<include/>也可以這麼理解,就是把某些通用的xml程式碼拷貝到<include/>所在的地方。以一個Activity為例。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:text="@string/hello" /> <include layout="@layout/footer_with_layout_properties"/> </RelativeLayout>
footer_with_layout_properties.xml中就是一個簡單的TextView,程式碼如下:
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp" android:gravity="center_horizontal" android:text="@string/footer_text" />
上述的程式碼中,我們使用了<include/>標籤,達到了程式碼複用的目的。
但是,仍然存在一些疑惑。
footer_with_layout_properties.xml中使用了android:layout_alignParentBottom屬性,這個屬性之所以可行,是因為外層佈局是RelativeLayout。
那麼,如果外層佈局換做LinearLayout又會怎樣呢?答案顯而易見,這肯定是行不通的。那麼怎麼辦呢?我們可以把具體的屬性寫在<include/>標籤裡面,看下面的程式碼。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:text="@string/hello"/> <include layout="@layout/footer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp"/> </RelativeLayout>
我們直接在<include/>標籤裡面使用了android:layout_*屬性。
注意:如果想要在<include/>標籤中覆蓋被包含佈局所指定的任何android:layout_*屬性,必須在<include/>標籤中同時指定layout_width和layout_height屬性,這可能是一個Android系統的一個bug吧。
ViewStub
在開發過程中,難免會遇到各種互動問題,例如顯示或隱藏某個檢視。如果想要一個檢視只在需要的時候顯示,可以嘗試使用ViewStub這個類。
先看一下ViewStub的官方介紹:
“ViewStub是一個不可視並且大小為0的檢視,可以延遲到執行時填充佈局資源。當ViewStub設定為Visible或呼叫inflate()之後,就會填充佈局資源,ViewStub便會被填充的檢視替代”。
現在已經清楚ViewStub能幹什麼了,那麼看一個例子。一個佈局中,存在一個MapView,只有需要它的時候,才讓它顯示出來。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:onClick="onShowMap" android:text="@string/show_map" /> <ViewStub android:id="@+id/map_stub" android:layout_width="fill_parent" android:layout_height="fill_parent" android:inflatedId="@+id/map_view" android:layout="@layout/map" /> </RelativeLayout>
map.xml檔案中包含一個MapView,只有在必要的時候,才會讓它顯示出來。
<com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map_view" android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="my_api_key" android:clickable="true" />
另外,inflatedId是ViewStub被設定成Visible或呼叫inflate()方法後返回的id,這個id就是被填充的View的id。在這個例子中,就是MapView的id。
接下來看看ViewStub是怎麼使用的。
public class MainActivity extends MapActivity { private View mViewStub; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mViewStub = findViewById(R.id.map_stub); } public void onShowMap(View v) { mViewStub.setVisibility(View.VISIBLE); } @Override protected boolean isRouteDisplayed() { return false; } }
題外話
有的同學肯定會問,使用ViewStub和單純地把View設定為View.GONE或View.VISIBLE有什麼區別呢?不都是顯示和隱藏嗎,使用ViewStub反而更麻煩了。
確實是有區別的,會涉及到View樹的渲染,記憶體消耗等。
至於有什麼具體的差別,就請大家自己去Google吧。俗話說,自己動手,豐衣足食嘛!
參考資料
http://code.google.com/p/android/issues/detail?id=2863
http://android-developers.blogspot.com.ar/2009/03/android-layout-tricks-3-optimize-with.html
http://developer.android.com/reference/android/view/ViewStub.html
相關文章
- 佈局優化之ViewStub、Include、merge使用分析優化View
- Android佈局優化之ViewStub、include、merge使用與原始碼分析Android優化View原始碼
- Android 佈局優化之includeAndroid優化
- Android 佈局優化Android優化
- Android優化之佈局優化Android優化
- Android效能優——佈局優化Android優化
- Android佈局優化技巧Android優化
- Android效能優化之佈局優化Android優化
- Android 優化之路(一)佈局優化Android優化
- Android繪製優化(二)佈局優化Android優化
- Android佈局檢測優化Android優化
- Android中佈局的優化Android優化
- Android佈局優化三劍客Android優化
- 佈局優化優化
- Android 效能優化(二)之佈局優化面面觀Android優化
- 轉:Android佈局優化三劍客Android優化
- Android學習之 UI佈局優化AndroidUI優化
- Android回顧--(十) ListView的優化和多佈局複用AndroidView優化
- Android——ConstraintLayout的使用,優化佈局效能AndroidAI優化
- Android最佳效能實踐(4):佈局優化技巧Android優化
- Android中常見的佈局和佈局引數Android
- iOS Flexbox 佈局優化iOSFlex優化
- 效能優化技巧知識梳理(1) 佈局優化優化
- rem佈局原理和優缺點REM
- Android 佈局Android
- 安卓程式碼、圖片、佈局、網路和電量優化安卓優化
- 姿勢擺好,一招學會android的佈局優化!Android優化
- 如何優化店鋪模板佈局——資訊圖優化
- 浮動佈局 和 flex佈局Flex
- Android佈局概述Android
- Android xml 佈局AndroidXML
- Web效能優化系列:預防佈局抖動Web優化
- Android中View繪製優化二一---- 使用標籤複用佈局檔案AndroidView優化
- android佈局------RelativeLayout(相對佈局)詳解Android
- android筆記二(水平佈局與垂直佈局)Android筆記
- Android學習—— Android佈局Android
- android 介面佈局(大概)Android
- CSS 兩欄佈局和三欄佈局CSS