在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]