定義Android Layout(XML)時,有四個比較特別的標籤是非常重要的,其中有三個是與資源複用有關,分別是<viewStub/>, <requestFocus />, <merge /> and<include />。可是以往我們所接觸的案例或者官方文檔的例子都沒有著重去介紹這些標籤的重要性。
1.)<viewStub />: 此標籤可以使UI在特殊情況下,直觀效果類似於設定View的不可見度,但是其更大的(R)意義在於被這個標籤所包裹的Views在預設狀態下不會佔用任 何記憶體空間。viewStub通過include從外部匯入Views元素。用法:通過android:layout來指定所包含的內容。預設情況 下,ViewStub所包含的標籤都屬於visibility=GONE。viewStub通過方法inflate()來召喚系統載入其內部的 Views。
<ViewStub android:id="@+id/stub"
android:inflatedId="@+id/subTree"
android:layout="@layout/mySubTree"
android:layout_width="120dip"
android:layout_height="40dip" />
2.)<include />:可以通過這個標籤直接載入外部的xml到當前結構中,是複用UI資源的常用標籤。用法:將需要複用xml檔案路徑賦予include標籤的Layout屬性。
<include android:id="@+id/cell1" layout="@layout/ar01" />
<include android:layout_width="fill_parent" layout="@layout/ar02" />
3.)<requestFocus />: 標籤用於指定螢幕內的焦點View。用法: 將標籤置於Views標籤內部
<EditText id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingBottom="4">
<requestFocus />
</EditText>
4.)<merge />:
單獨將<merge />標籤做個介紹,是因為它在最佳化UI結構時起到很重要的作用。目的是通過刪減多餘或者額外的層級,從而最佳化整個Android Layout的結構。
將通過一個例子來瞭解這個標籤實際所產生的作用,這樣可以更直觀的瞭解<merge/>的用法。
建立一個簡單的Layout,其中包含兩個Views元素:ImageView和TextView 預設狀態下我們將這兩個元素放在FrameLayout中。其效果是在主視圖中全螢幕顯示一張圖片,之後將標題顯示在圖片上,並位於視圖的下方。以下是xml代碼:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/golden_gate" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"
android:padding="12dip"
android:background="#AA000000"
android:textColor="#ffffffff"
android:text="Golden Gate" />
</FrameLayout>
應用上邊的Layout啟動並執行視圖為:
啟動 tools> hierarchyviewer.bat工具查看當前UI結構視圖:
我 們可以很明顯的看到由紅色線框所包含的結構出現了兩個framelayout節點,很明顯這兩個完全意義相同的節點造成了資源浪費(這裡可以提醒大家在開 發工程中可以習慣性的通過hierarchyViewer查看當前UI資源的分配情況),那麼如何才能解決這種問題呢(就當前例子是如何去掉多餘的 frameLayout節點)?這時候就要用到<merge />標籤來處理類似的問題了。我們將上邊xml代碼中的framLayout替換成merge:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/golden_gate" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"
android:padding="12dip"
android:background="#AA000000"
android:textColor="#ffffffff"
android:text="Golden Gate" />
</merge>
運 行程式後在Emulator中顯示的效果是一樣的,可是通過hierarchyviewer查看的UI結構是有變化的,當初多餘的 FrameLayout節點被合并在一起了,或者可以理解為將merge標籤中的子集直接加到Activity的FrameLayout跟節點下(這裡需 要提醒大家注意:所有的Activity視圖的根節點都是frameLayout)。如果你所建立的Layout並不是用framLayout作為根節點 (而是應用LinerLayout等定義root標籤),就不能應用上邊的例子通過merge來最佳化UI結構。
除了上邊的例子外,meger還有另外一個用法
當應用Include或者ViewStub標籤從外部匯入xml結構時,可以將被匯入的xml用merge作為根節點表示,這樣當被嵌入父級結構中後可以很好的將它所包含的子集融合到父級結構中,而不會出現冗餘的節點。
另外有兩點需要特別注意:
<merge />只可以作為xml layout的根節點。當需要擴充的xml layout本身是由merge作為根節點的話,需要將被匯入的xml layout置於 viewGroup中,同時需要設定attachToRoot為True。