本文转载自 http://www.cnblogs.com/xirihanlin/archive/2010/04/28/1723291.html
多亏了 <include /> 标签,在 Android 里,很容易就能做到共享和重用 UI 组件。在 Android 开发中,很容易就能创建出复杂的 UI 结构,结果呢,用了很多的 View ,且其中的一些很少使用。针对这种情况,谢天谢地, Android 还为我们提供了一个特别的构件—— ViewStub ,它可以使你充分享受 <include /> 的好处而不会造成无用 View 的浪费。
ViewStub 是一个看不见的,轻量级的 View 。它没有尺寸,也不会绘制以及以某种形式参与到布局中来。这意味着 ViewStub 去 inflate 以及保留在 View 层次中的代价是很廉价的。 ViewStub 最佳的描述称之为“懒惰的 include ”。 ViewStub 中引用的布局只在你想添加到 UI 上时才会显示。
下面的截图来自于 Shelves 应用程序。图中 Activity 显示的内容是给用户呈现可浏览的书籍列表:
相同的 Activity 也用于用户添加或导入新的书籍。在这个操作中, Shelves 显示了一个额外的 UI 。下面的截图显示了在导入期间,会在屏幕的底部显示一个进度表和一个取消按钮:
由于导入书籍不是一个常有的操作,至少相对于浏览书籍列表来说不是,因此,导入 panel 由 ViewStub 来承载:
当用户进行一个导入操作时, ViewStub 被 inflate ,此时由它引用的布局文件内容替代显示:
为了使用 ViewStub ,你所有需要做的是指定 android:id 特性,便于以后 inflate ,指定 android:layout 特性,引用布局文件。 ViewStub 还允许你使用第三个特性, android:inflatedId ,你可以使用它来重写包含的布局文件中的根元素的 id 。最后,在 ViewStub 上设定的 layout_* 参数将会应用到包含的布局文件的顶部。这里有个例子:
<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"
android:layout="@layout/progress_overlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
当你准备 inflate ViewStub 时,调用 inflate() 方法即可。你还可以设定 ViewStub 的 Visibility 为 VISIBLE 或 INVISIBLE ,也会触发 inflate 。注意的是,使用 inflate() 方法能返回布局文件的根 View :
((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
有一点需要记住的是:当 ViewStub inflate 后,这个 ViewStub 就从 View 层次中移除了。因此,没有必要保留一个对 ViewStub 的引用(如在类的字段里)。
ViewStub 是快捷编程与高效编程之间的产物。与其手动的 inflate View 并在运行时添加到 View 层次上,不如简单的使用 ViewStub 。它相当“廉价”且易于使用。 ViewStub 唯一的缺点是现在不支持 <merge /> 标签。