ViewStub(惰性控件/延时加载)

  在Android开发中,经常会遇到这样的情况,一个界面中某一部分布局不需要马上显示,而要等到用户点击“展开”后才加载,亦或者是有意的延时加载,这时就可以使用惰性控件ViewStub来方便的完成这一功能。

  惰性控件ViewStub是一个轻量级的View,可以实现动态布局加载。ViewStub对象是一个看不见的,零大小的视图,并在程序运行时根据需要进行动态加载。只有当ViewStub对象被设置为可见(调用setVisibility()方法),或是调用了inflate()方法时,ViewStub对象所指向的布局才会被实例化,并加载到父布局中(原来的ViewStub里面)。这样,便通过惰性控件ViewStub实现了动态加载某个控件或布局。


Java文件:

package com.plusjun.hello3;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	View v1;
	Button bt1,bt2,bt3;
	ViewStub viewstub1;
	TextView tv1;
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		bt1 = (Button)findViewById(R.id.bt1);
		bt2 = (Button)findViewById(R.id.bt2);
		bt3 = (Button)findViewById(R.id.bt3);
		viewstub1 = (ViewStub)findViewById(R.id.viewstub1);
		//inflate方法在一个ViewStub中只能使用一次,因为该方法实例化了该布局,并将指定的布局文件,
		//覆盖在原来ViewStub所在的位置(应该叫替换)所以该方法只能使用一次
		//同时,返回一个View。如果以后要操作这个布局里面的控件,
		//则要通过这个View来获取
		//创建完之后,默认为显示状态
		v1 = viewstub1.inflate();
		//这个TextView就是上面返回的View里面的控件。
		//因为你用的是别的Layout,而不是这个Activity里面setContentView的Layout。
		tv1 = (TextView)v1.findViewById(R.id.tv1);
		bt1.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				//显示
				v1.setVisibility(View.VISIBLE);
			}
		});
		bt2.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				//隐藏
				v1.setVisibility(View.INVISIBLE);
			}
		});
		bt3.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				//完全隐藏,不占用位置
				v1.setVisibility(View.GONE);
			}
		});
	}
}
activity_main.xml文件。在该文件中,我们通过语句android:layout="@layout/viewstublayout"指定了惰性控件ViewStub所要动态加载的布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <ViewStub
        android:id="@+id/viewstub1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/viewstublayout" >
    </ViewStub>

    <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="VISIBLE" />

    <Button
        android:id="@+id/bt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="INVISIBLE" />
    
    <Button
        android:id="@+id/bt3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GONE" />

</LinearLayout>
viewstublayout文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="null" />

</LinearLayout>

  在开发文档中可看到,方法inflate()会调用getLayoutResource()方法标识的布局资源,并通过加载布局资源放到原来的ViewStub中(可以把原来的ViewStub想像成一个不占位置的框)。方法setVisibility (int visibility),当可见性设置为VISIBLE或INVISIBLE时,inflate()都将被调用(从头到尾只会调用一次)。方法setVisibility可以设置的VISIBLE(显示),INVISIBLE(隐藏),GONE(完全隐藏,不占用布局位置)。要记住,在方法inflate()调用的一刻,也就已经实例化了,也就是开始占用CPU和内存了。因此,ViewStub另一个很重要的用途在于缓解载入界面的卡顿,有意的延迟载入,可以加快初始界面生成速度。


以上部分内容转载或参考来源如下:

http://www.cnblogs.com/menlsh/archive/2013/03/17/2965217.html

http://blog.csdn.net/hitlion2008/article/details/6737537

http://www.blogjava.net/gaolei-xj/archive/2013/02/17/395348.html

在此表示感谢。
转载请注明来源,版权归原作者所有,未经同意严禁用于任何商业用途。
微博:http://weibo.com/theworldsong
邮箱:[email protected]

你可能感兴趣的:(android,ViewStub)