您的位置:首页 > 移动开发 > Android开发

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

2013-06-26 11:18 316 查看
  在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

邮箱:theworldsong@foxmail.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android ViewStub