ViewStub和DataBinding使用方法

4,238 阅读2分钟

以下是Android官方文档的使用说明

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)方法,测试中是否调用这个方法对结果没有影响,如果有小伙伴了解这个方法,请留言告知,谢谢。