由於最近正在封裝下拉刷新上拉加載的庫,爲了進一步的優化ui,所以學習了下ViewStub,這裏轉載別人的blog分享給大家.
原文地址http://www.cnblogs.com/menlsh/archive/2013/03/17/2965217.html
在Android開發中,經常會遇到這樣的情況,在程序運行過程中動態的根據當前條件來決定是否顯示某個控件或佈局,那麼最通常的想法就是把可能用到的View都寫在上面,先把它們的可見性都設爲View.GONE,然後在代碼中動態的更改它的可見性。這樣的做法的優點是邏輯簡單而且控制起來比較靈活。但是它的缺點就是,耗費資源。雖然把View的初始可見View.GONE但是在Inflate佈局的時候View仍然會被Inflate,也就是說仍然會創建對象,會被實例化,會被設置屬性。也就是說,會耗費內存等資源.這時就可以使用惰性控件ViewStub來方便的完成這一功能。
惰性控件ViewStub是一個輕量級的View,可以實現動態佈局加載。ViewStub對象是一個看不見的,零大小的視圖,並在程序運行時根據需要進行動態加載。只有當ViewStub對象被設置爲可見,或是調用了ViewStub.inflate()方法時,ViewStub對象所指向的佈局纔會被實例化,並加載到指向的父佈局中。這樣,便通過惰性控件ViewStub實現了動態加載某個控件或佈局。並且優化了性能.
在本篇博文中,我們將通過一個實例來演示如何使用惰性控件ViewStub完成動態加載佈局操作。完成後的程序運行效果如圖所示。
在如圖1所示的主界面中,點擊“展開寶貝詳細描述”按鈕,將通過惰性控件ViewStub加載動態佈局的方式,引入一段對商品的文字描述信息,如圖2所示。
從圖2可以看出,通過使用惰性控件ViewStub,我們在原佈局中動態的加入了一段有關商品的描述信息。當點擊“隱藏寶貝詳細描述”按鈕時,這段商品描述信息將被隱藏,主界面將重新變爲圖1所示的顯示效果。
下面就來說說該實例的具體實現方法。
1.靜態加載佈局
在講解使用惰性控件ViewStub動態加載佈局之前,有必要先說說靜態加載佈局。
在Android開發中,有時一個UI界面是及其複雜的,其中包含了衆多佈局模塊和控件,如果將其寫在一個xml佈局文件中,不僅代碼冗餘,而且代碼可讀性也很差,不易進行後期代碼維護。
這時,我們可以將一個複雜的UI界面分解成幾個獨立的子模塊,併爲每一個子模塊編寫單獨的xml佈局文件。在父佈局中,使用標籤將各個子模塊佈局文件加載進來即可。
這樣便實現了UI界面的靜態加載佈局。
在該實例中,我們便將主界面上方的商品圖片和寶貝評價定義在了一個單獨的xml文件“includelayout.xml”中,然後在主界面佈局文件中通過標籤將其靜態的加載進來,具體實現方法如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- 靜態加載 -->
<include
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="@layout/includelayout" >
</include>
<ViewStub
android:id="@+id/viewstub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout="@+layout/viewstublayout" >
</ViewStub>
<!-- 按鈕 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/button_extend"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="展開寶貝詳細描述" />
<Button
android:id="@+id/button_hide"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="隱藏寶貝詳細描述" />
</LinearLayout>
</LinearLayout>
如上,我們使用語句layout=”@layout/includelayout”在標籤中靜態的加載了“includelayout.xml”佈局文件中。在“includelayout.xml”佈局文件中,我們實現了商品圖片、寶貝評價以及寶貝評分控件的佈局設計。
2.惰性控件ViewStub
通過以上的代碼不難看出,在主佈局文件中,我們在Button按鈕控件的上面設置了一個惰性控件ViewStub。在惰性控件ViewStub中,我們通過語句android:layout=”@+layout/viewstublayout”指定了惰性控件ViewStub所要動態加載的佈局是“viewstublayout.xml”文件。在“viewstublayout.xml”文件中我們通過TextView控件來顯示商品的詳細描述信息。具體實現方法如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="品牌:卡馬 KEPMA" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="型號:D1C" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="規格:41寸" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="面板:雲杉木" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="底側:南洋木" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="弦鈕:鍍黑鎳打鋼印全封閉弦鈕" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="包邊:珍珠條鑲嵌" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="品味:21品" />
</LinearLayout>
3.惰性控件ViewStub的加載
至此,我們已經定義好了惰性控件ViewStub,並指定了惰性控件ViewStub所要動態加載的具體內容。那麼如何在程序運行過程中加載惰性控件ViewStub呢?
先來了解一下惰性控件ViewStub的常用方法,如圖3所示。
其中,方法inflate()用於加載getLayoutResource()方法標識的佈局資源,並通過加載佈局資源替換父容器中它自己。方法setVisibility (int visibility),當可見性設置爲VISIBLE或INVISIBLE時,inflate()都將被調用,並且加載視圖資源在父容器中替換ViewStub。參數visibility可以設置的值有VISIBLE(顯示),INVISIBLE(隱藏),GONE(完全隱藏,不佔用佈局位置)。
由此,我們可以爲該實例中的兩個Button按鈕添加事件監聽器OnClickListener,並實現該接口中的方法onClick()如下:
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_extend: //點擊“展開”按鈕時顯示ViewStub控件內容
View view = mViewStub.inflate();
LinearLayout linearLayout = (LinearLayout)view;
break;
case R.id.button_hide: //點擊“隱藏”按鈕時隱藏ViewStub控件內容
mViewStub.setVisibility(View.GONE);
break;
}
}
4.注意事項
在使用惰性控件ViewStub時需要特別注意:
(1)ViewStub對象只可以Inflate一次,之後ViewStub對象會被置爲空。按句話說,某個被ViewStub對象指定的佈局被Inflate一次之後,就不可以再次通過ViewStub對象來控制它了。
(2)ViewStub控件只能用來Inflate一個佈局文件,而不能Inflate某個具體的View。
(3)某些佈局屬性要加在ViewStub而不是實際的佈局上面,纔會起作用,比如android:layout_margin*系列屬性,如果加在TextView上面,則不會起作用,需要放在它的ViewStub上面纔會起作用。而ViewStub的屬性在inflate()後會都傳給相應的佈局。