一、前言
ViewStub 是布局优化的方式之一,适用于一些延迟加载的场景,相对于设置 View.GONE<br />的优点是逻辑简单控制灵活,但是缺点也很明显,更耗资源,不管可见不可见都会被创建。ViewStub更加轻量级,它本身是一个不可见不占用位置的 View,资源消耗比较小,只有调用了ViewStub.inflate()的时候加载布局,布局才会实例化。
<a name="6QFnm"></a>
二、使用
先看效果图:<br /> iShot2020-07-1316.56.08.gif- 布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/tv_viewstub_title"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="viewstub 的简单使用"
android:textSize="17sp"
android:textColor="@color/white"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
android:background="@color/black_999999"/>
<Button
android:id="@+id/btn_viewstub_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示"
app:layout_constraintTop_toBottomOf="@+id/tv_viewstub_title"
app:layout_constraintLeft_toLeftOf="parent"/>
<Button
android:id="@+id/btn_viewstub_hide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="隐藏"
app:layout_constraintTop_toBottomOf="@+id/tv_viewstub_title"
app:layout_constraintLeft_toRightOf="@+id/btn_viewstub_show"/>
<Button
android:id="@+id/btn_viewstub_midify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改内容"
app:layout_constraintTop_toBottomOf="@+id/tv_viewstub_title"
app:layout_constraintLeft_toRightOf="@+id/btn_viewstub_hide"/>
<ViewStub
android:id="@+id/vs_viewstub_sv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
app:layout_constraintTop_toBottomOf="@+id/tv_viewstub_title"
android:layout="@layout/include_layout"/>
</androidx.constraintlayout.widget.ConstraintLayout>
- 延迟加载的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/rl_viewstub_outer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/colorPrimary"
>
<TextView
android:id="@+id/tv_include_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="可以改变的内容"
android:textSize="20sp"
android:textColor="@color/white"
android:layout_centerInParent="true"/>
</RelativeLayout>
- activity
class ViewStubActivity: AppCompatActivity() {
var inflate: View? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_viewstub)
btn_viewstub_show.setOnClickListener {
//inflate 只能调用一次
if (inflate == null){
inflate = vs_viewstub_sv.inflate()
}
//调用这个方法会闪退,viewstub 加载过后就会被移除
//vs_viewstub_sv.visibility = View.VISIBLE
rl_viewstub_outer.visibility = View.VISIBLE
}
btn_viewstub_hide.setOnClickListener {
//vs_viewstub_sv.visibility = View.GONE
rl_viewstub_outer.visibility = View.GONE
}
btn_viewstub_midify.setOnClickListener {
//在 viewStub inflate 之前不可调用
// tv_include_layout.text = "任意改变的内容"
if (inflate == null){
inflate = vs_viewstub_sv.inflate()
tv_include_layout.text = "修改过后的内容"
}else{
tv_include_layout.text = "修改过后的内容"
}
}
}
}
<a name="i7Crk"></a>
三、注意事项
- ViewStub只能Inflate一次,之后ViewStub对象会被置为空。
- ViewStub只能用来Inflate一个布局文件,而不是某个具体的View
- 想要控制显示与隐藏的是一个布局文件,而非某个View。
- 某些布局属性要加在ViewStub而不是实际的布局上面,才会起作用,比如上面用的android:layout_margin*系列属性,如果加在TextView上面,则不会起作用,需要放在它的ViewStub上面才会起作用。而ViewStub的属性在inflate()后会都传给相应的布局。
<br />
<a name="Y0Au1"></a>
网友评论