ViewStubs
与普通视图不同,ViewStub对象初始是一个不可见视图。当它们显示出来或者获得明确指示进行扩充时,
它们会通过扩充另一个布局在布局中完成自我取代。
由于 ViewStub 实际上会从视图层次结构中消失,因此绑定对象中的视图也必须消失,才能通过垃圾回收进行回收。
由于视图是最终结果,因此 ViewStubProxy对象将取代生成的绑定类中的 ViewStub,让您能够访问ViewStub(如果存在),
同时还能访问 ViewStub 进行扩充后的扩充版视图层次结构。
在扩充其他布局时,必须为新布局建立绑定。
因此,ViewStubProxy 必须监听 ViewStub OnInflateListener并在必要时建立绑定。
由于在给定时间只能有一个监听器,因此 ViewStubProxy 允许您设置OnInflateListener,它将在建立绑定后调用这个监听器。
官方文档只强调了要在ViewStub导入布局文件时要用户去建立绑定关系。 以下是建立绑定关系的步骤:
1、首先设置监听OnInflateListener,并在其中对视图绑定类进行数据绑定
var viewStupTestBinding:ViewStupTestBinding? = null
###onCreate
// activityMainBinding.vsTest.setContainingBinding(activityMainBinding)
activityMainBinding.vsTest.setOnInflateListener { _, _ ->
activityMainBinding.vsTest.binding?.let {
viewStupTestBinding = it as ViewStupTestBinding
viewStupTestBinding?.data = loginViewModel
viewStupTestBinding?.lifecycleOwner = this
}
}
2、在需要导入布局的方法中添加以下代码:
activityMainBinding.vsTest.viewStub?.let {
it.inflate()
}
经过以上两步就可以在我们要导入的视图中正常访问我们要绑定的ViewModel了,其中vsTest是ViewStub标签的id,ViewStupTestBinding是系统按照布局文件R.layout.view_stup_test自动生成的数据绑定类。
view_stup_test.xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="personal.zach.roombasicdemo.LoginViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_sentiment_satisfied_black_24dp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{data.userName,default=测试}"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
LoginViewModel文件如下:
class LoginViewModel:ViewModel() {
var remember: MutableLiveData<Boolean> = MutableLiveData(true)
var userName:MutableLiveData<String> = MutableLiveData()
}
以上作为记录,如有不足请同学们指正。
另外,ViewStubProxy有一个public void setContainingBinding(@NonNull ViewDataBinding containingBinding)方法,测试中是否调用这个方法对结果没有影响,如果有小伙伴了解这个方法,请留言告知,谢谢。