<ViewStub>
标签实质上是一个宽高都为 0 的不可见 View. 通过延迟加载布局的方式优化布局提升渲染性能.
这里的延迟加载是指初始化时, 程序无需显示该标签所指向的布局文件, 只有在特定的条件下, 所指向的布局文件才需要被渲染, 且此布局文件直接将当前的 <ViewStub>
替换掉. 但这里的替换并不是完全意义上的替换, 布局文件的 layout params 是以 ViewStub 为优先.
当初次渲染布局文件时, ViewStub 控件虽然也占据内存, 但是相比于其他控件, 它所占内存很小. 它主要是作为一个“占位符”, 放置于 View Tree中, 且它本身是不可见的.
使用场景
通常用于不常使用的控件. 比如
- 网络请求失败的提示
- 列表为空的提示
- 新内容、新功能的引导, 因为引导基本上只显示一次
- 又或者我们写了一个通用的自定义 View. 但其中部分子 View 只在部分情况下才显示.
怎么用
<ViewStub
android:id="@+id/view_stub"
android:layout="@layout/layout_to_show"
android:layout_width="match_parent"
android:layout_height="match_parent" />
要被加载的布局通过 android:layout
属性来设置. 然后在程序中调用 inflate()
方法来加载. 还可以设定 Visibility 为 VISIBLE 或 INVISIBLE, 也会触发 inflate()
. 但只有直接使用 inflate()
方法能返回布局文件的根 View. 但是这里只会在首次使用 setVisibility()
会加载要渲染的布局文件. 再次使用只是单纯的设置可见性.
对 inflate()
操作也只能进行一次, 因为 inflate()
的时候是其指向的布局文件替换掉当前 <ViewStub>
标签. 之后, 原来的布局文件中就没有 <ViewStub>
标签了. 因此, 如果多次 inflate()
操作, 会报错: ViewStub must have a non-null ViewGroup viewParent