在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 <ViewStub 15 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 <Button 28 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 <Button 34 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。