一、前言

ViewStub 是布局优化的方式之一,适用于一些延迟加载的场景,相对于设置 View.GONE
的优点是逻辑简单控制灵活,但是缺点也很明显,更耗资源,不管可见不可见都会被创建。ViewStub更加轻量级,它本身是一个不可见不占用位置的 View,资源消耗比较小,只有调用了ViewStub.inflate()的时候加载布局,布局才会实例化。

二、使用

先看效果图:
iShot2020-07-1316.56.08.gif

  • 布局文件 ``` <?xml version=”1.0” encoding=”utf-8”?>

    <Button

    1. android:id="@+id/btn_viewstub_show"
    2. android:layout_width="wrap_content"
    3. android:layout_height="wrap_content"
    4. android:text="显示"
    5. app:layout_constraintTop_toBottomOf="@+id/tv_viewstub_title"
    6. app:layout_constraintLeft_toLeftOf="parent"/>
  1. <ViewStub
  2. android:id="@+id/vs_viewstub_sv"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:layout_marginTop="100dp"
  6. app:layout_constraintTop_toBottomOf="@+id/tv_viewstub_title"
  7. android:layout="@layout/include_layout"/>

  1. - 延迟加载的布局

<?xml version=”1.0” encoding=”utf-8”?>

  1. <TextView
  2. android:id="@+id/tv_include_layout"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. android:text="可以改变的内容"
  6. android:textSize="20sp"
  7. android:textColor="@color/white"
  8. android:layout_centerInParent="true"/>

  1. - activity

class ViewStubActivity: AppCompatActivity() { var inflate: View? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_viewstub)

  1. btn_viewstub_show.setOnClickListener {
  2. //inflate 只能调用一次
  3. if (inflate == null){
  4. inflate = vs_viewstub_sv.inflate()
  5. }
  6. //调用这个方法会闪退,viewstub 加载过后就会被移除
  7. //vs_viewstub_sv.visibility = View.VISIBLE
  8. rl_viewstub_outer.visibility = View.VISIBLE
  9. }
  10. btn_viewstub_hide.setOnClickListener {
  11. //vs_viewstub_sv.visibility = View.GONE
  12. rl_viewstub_outer.visibility = View.GONE
  13. }
  14. btn_viewstub_midify.setOnClickListener {
  15. //在 viewStub inflate 之前不可调用
  16. // tv_include_layout.text = "任意改变的内容"
  17. if (inflate == null){
  18. inflate = vs_viewstub_sv.inflate()
  19. tv_include_layout.text = "修改过后的内容"
  20. }else{
  21. tv_include_layout.text = "修改过后的内容"
  22. }
  23. }
  24. }

} ```

三、注意事项

    1. ViewStub只能Inflate一次,之后ViewStub对象会被置为空。
    1. ViewStub只能用来Inflate一个布局文件,而不是某个具体的View
    1. 想要控制显示与隐藏的是一个布局文件,而非某个View。
    1. 某些布局属性要加在ViewStub而不是实际的布局上面,才会起作用,比如上面用的android:layout_margin*系列属性,如果加在TextView上面,则不会起作用,需要放在它的ViewStub上面才会起作用。而ViewStub的属性在inflate()后会都传给相应的布局。


参考

ViewStub用法
Android进阶——布局优化之灵活借助ViewStub实现懒加载
Android UI布局优化之ViewStub