1. 程式人生 > >Android之viewstub用法詳解及實現延遲載入

Android之viewstub用法詳解及實現延遲載入

上一篇的佈局中間就用了viewstub這個控制元件,現在來說一下其作用和用法

"

 ViewStub 是一個不可見的,大小為0的View,最佳用途就是實現View的延遲載入,避免資源浪費,在需要的時候才載入View

"

需要注意的是,載入view之後,viewstub本身就會被新載入進來的view替換掉

上程式碼了,看完就理解了

acitivity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <include
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="30dp"
        layout="@layout/header" />

    <ViewStub
        android:id="@+id/pic_stub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:inflatedId="@+id/pic_view_id_after_inflate"
        android:layout="@layout/pic_view" />


    <include layout="@layout/footer" />

</RelativeLayout>


其中inflatedId就是新載入進來的view的id,如果需要獲取這個view,就要用這個inflatedId,原來的id已經被取代了

而layout就是要載入進來的佈局,程式碼如下

pic_view.xml

<?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" >

    <ImageView
        android:id="@+id/iv_pic"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/pic" >
    </ImageView>

</LinearLayout>


裡面只放了一張圖片

MainActivity.java

public class MainActivity extends Activity {
	private ViewStub pic_sub;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		pic_sub = (ViewStub) findViewById(R.id.pic_stub);
		new Timer().schedule(new TimerTask() {

			@Override
			public void run() {
				handler.sendEmptyMessage(1);
			}
		}, 1000);// 延遲1秒,然後載入
	}

	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			View pic_view = pic_sub.inflate();// ①
			//pic_sub.setVisibility(View.VISIBLE);// ②
			ImageView iv_pic = (ImageView) pic_view.findViewById(R.id.iv_pic);
			iv_pic.setImageResource(R.drawable.pic);
			View view = findViewById(R.id.pic_stub);//③
			view = findViewById(R.id.pic_view_id_after_inflate);//④
		};
	};
}

inflate()被呼叫時, 被載入的檢視替代viewstub並且返回自己的檢視物件。這使得應用程式不需要額外執行findViewById()來獲取所載入的檢視的引用

②句不需要,如果用到setvisibility的話,那麼①②兩句順序不可顛倒,否則報錯

java.lang.IllegalStateException:ViewStub must have a non-null ViewGroup viewParent,因為viewstub不能反覆inflate,只能inflate一次,setVisibility會間接呼叫inflate


①句 獲取到載入進來的pic_view,使得應用程式不需要額外執行findViewById()來獲取載入檢視的引用,如果要自己獲取的話,id要用inflateid

③句  這裡view將會是null,因為viewstub被替換掉,pic_stub的id已經不存在了

④句  用inflateid獲取到載入進來的view正常

作者:jason0539