在Android開發中,經常會遇到這樣的情況,在程式運行過程中動態根據當前條件來決定是否顯示某個控制項或布局,這時就可以使用惰性控制項ViewStub來方便的完成這一功能。
惰性控制項ViewStub是一個輕量級的View,可以實現動態布局載入。ViewStub對象是一個看不見的,零大小的視圖,並在程式運行時根據需要進行動態載入。只有當ViewStub對象被設定為可見,或是調用了ViewStub.inflate()方法時,ViewStub對象所指向的布局才會被執行個體化,並載入到指向的父布局中。這樣,便通過惰性控制項ViewStub實現了動態載入某個控制項或布局。
在本篇博文中,我們將通過一個執行個體來示範如何使用惰性控制項ViewStub完成動態載入布局操作。完成後的程式運行效果1所示。
圖1 主介面顯示效果
在1所示的主介面中,點擊“展開寶貝詳細描述”按鈕,將通過惰性控制項ViewStub載入動態布局的方式,引入一段對商品的文字描述資訊,2所示。
圖2 動態載入布局效果
從圖2可以看出,通過使用惰性控制項ViewStub,我們在原布局中動態加入了一段有關商品的描述資訊。當點擊“隱藏寶貝詳細描述”按鈕時,這段商品描述資訊將被隱藏,主介面將重新變為圖1所示的顯示效果。
下面就來說說該執行個體的具體實現方法。
1.靜態載入布局
在講解使用惰性控制項ViewStub動態載入布局之前,有必要先說說靜態載入布局。
在Android開發中,有時一個UI介面是及其複雜的,其中包含了眾多布局模組和控制項,如果將其寫在一個xml布局檔案中,不僅代碼冗餘,而且代碼可讀性也很差,不易進行後期代碼維護。
這時,我們可以將一個複雜的UI介面分解成幾個獨立的子模組,並為每一個子模組編寫單獨的xml布局檔案。在父布局中,使用<include></include>標籤將各個子模組布局檔案載入進來即可。
這樣便實現了UI介面的靜態載入布局。
在該執行個體中,我們便將主介面上方的商品圖片和寶貝評價定義在了一個單獨的xml檔案“includelayout.xml”中,然後在主介面布局檔案中通過<include>標籤將其靜態載入進來,具體實現方法如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" > 6 7 <!-- 靜態載入 --> 8 <include 9 android:layout_width="wrap_content"10 android:layout_height="wrap_content"11 layout="@layout/includelayout" >12 </include>13 14 <ViewStub15 android:id="@+id/viewstub"16 android:layout_width="wrap_content"17 android:layout_height="wrap_content"18 android:layout_marginLeft="2dp"19 android:layout="@+layout/viewstublayout" >20 </ViewStub>21 22 <!-- 按鈕 -->23 <LinearLayout 24 android:orientation="horizontal"25 android:layout_width="match_parent"26 android:layout_height="wrap_content" >27 <Button28 android:id="@+id/button_extend"29 android:layout_weight="1"30 android:layout_width="wrap_content"31 android:layout_height="wrap_content"32 android:text="展開寶貝詳細描述" />33 <Button34 android:id="@+id/button_hide"35 android:layout_weight="1"36 android:layout_width="wrap_content"37 android:layout_height="wrap_content"38 android:text="隱藏寶貝詳細描述" />39 </LinearLayout>40 41 </LinearLayout>
如上,我們使用語句layout="@layout/includelayout"在<include>標籤中靜態載入了“includelayout.xml”布局檔案中。在“includelayout.xml”布局檔案中,我們實現了商品圖片、寶貝評價以及寶貝評等控制項的布局設計。
2.惰性控制項ViewStub
通過以上的代碼不難看出,在主布局檔案中,我們在Button按鈕控制項的上面設定了一個惰性控制項ViewStub。在惰性控制項ViewStub中,我們通過語句android:layout="@+layout/viewstublayout"指定了惰性控制項ViewStub所要動態載入的布局是“viewstublayout.xml”檔案。在“viewstublayout.xml”檔案中我們通過TextView控制項來顯示商品的詳細描述資訊。具體實現方法如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <TextView 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content"10 android:text="品牌:卡馬 KEPMA" />11 <TextView 12 android:layout_width="match_parent"13 android:layout_height="wrap_content"14 android:text="型號:D1C" />15 <TextView 16 android:layout_width="match_parent"17 android:layout_height="wrap_content"18 android:text="規格:41寸" /> 19 <TextView 20 android:layout_width="match_parent"21 android:layout_height="wrap_content"22 android:text="面板:雲杉木" />23 <TextView 24 android:layout_width="match_parent"25 android:layout_height="wrap_content"26 android:text="底側:南洋木" /> 27 <TextView 28 android:layout_width="match_parent"29 android:layout_height="wrap_content"30 android:text="弦鈕:鍍黑鎳打鋼印全封閉弦鈕" />31 <TextView 32 android:layout_width="match_parent"33 android:layout_height="wrap_content"34 android:text="包邊:珍珠條鑲嵌" /> 35 <TextView 36 android:layout_width="match_parent"37 android:layout_height="wrap_content"38 android:text="品味:21品" /> 39 40 </LinearLayout>
3.惰性控制項ViewStub的載入
至此,我們已經定義好了惰性控制項ViewStub,並指定了惰性控制項ViewStub所要動態載入的具體內容。那麼如何在程式運行過程中載入惰性控制項ViewStub呢?
先來瞭解一下惰性控制項ViewStub的常用方法,3所示。
圖3 惰性控制項ViewStub的常用方法
其中,方法inflate()用於載入getLayoutResource()方法標識的布局資源,並通過載入布局資源替換父容器中它自己。方法setVisibility (int visibility),當可見度設定為VISIBLE或INVISIBLE時,inflate()都將被調用,並且載入視圖資源在父容器中替換ViewStub。參數visibility可以設定的值有VISIBLE(顯示),INVISIBLE(隱藏),GONE(完全隱藏,不佔用布局位置)。
由此,我們可以為該執行個體中的兩個Button按鈕添加事件監聽器OnClickListener,並實現該介面中的方法onClick()如下:
1 /* 2 * Function : 事件監聽處理 3 * Author : 部落格園-依舊淡然 4 */ 5 public void onClick(View v) { 6 switch (v.getId()) { 7 case R.id.button_extend: //點擊“展開”按鈕時顯示ViewStub控制項內容 8 View view = mViewStub.inflate(); 9 LinearLayout linearLayout = (LinearLayout)view;10 break;11 case R.id.button_hide: //點擊“隱藏”按鈕時隱藏ViewStub控制項內容12 mViewStub.setVisibility(View.GONE);13 break;14 }15 }
4.兩點注意
在使用惰性控制項ViewStub時有兩點需要特別注意:
(1)ViewStub對象只可以Inflate一次,之後ViewStub對象會被置為空白。按句話說,某個被ViewStub對象指定的布局被Inflate一次之後,就不可以再次通過ViewStub對象來控制它了。
(2)ViewStub控制項只能用來Inflate一個布局檔案,而不能Inflate某個具體的View。