Android DataBinding之布局include 和 viewStub详解与使用(六)

一、介绍

        前面几章节,我们已系统的学习了布局和数据的绑定,都是涉及到布局和数据的更细部分,这个章节我们依旧介绍一个使用频率很多的两个布局include 和viewStub

二、使用介绍

1、include

                布局导入,在我们开发过程中经常遇到,将一个公共组件view抽取成一个布局,然后用的使用include进来。这样方便我们大家协同开发。如果我们通过databind来管理,这样就很官方。只要我们将数据模块给到include的layout,这样我们就可以不用管理布局里面的,只需要单独处理好数据即可。

1.1、根布局

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">

    <data class="MyConstan">


        <import type="androidx.databinding.ObservableField" />


        <variable
            name="name"
            type="ObservableField&lt;String&gt;" />

    </data>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <Button
            android:id="@+id/btn_bind"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="单向绑定"
            />

        <include
            layout="@layout/view_db_include"
            bind:name="@{name}" />

    </LinearLayout>


</layout>

include子布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>


        <import type="androidx.databinding.ObservableField" />


        <variable
            name="name"
            type="ObservableField&lt;String&gt;" />

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="include module" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="@{name}" />

    </LinearLayout>
</layout>

布局数据交互:

如果在子布局data节点下定义了variable数据类型,那么这个数据就是根布局include的扩展字段

子布局:

 <variable
            name="name"
            type="ObservableField&lt;String&gt;" />

根布局:bind:name="@{name}"

        数据格式要对应。这样数据就可以绑定关联起来,支持数据单向和双向绑定,在绑定数据的时候,只需要设置好根布局的data数据即可。

2、ViewStub

        ViewStub在大型负责的布局业务开发过程中也常常被用到,即用到再加载,这样可以提升设备性能。减少不需要的内存开销

在Data Binding中,同样也支持ViewStub的绑定

根布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">

    <data class="MyConstan">


        <import type="androidx.databinding.ObservableField" />


        <variable
            name="name"
            type="ObservableField&lt;String&gt;" />

    </data>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <Button
            android:id="@+id/btn_bind"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="单向绑定"
            />


        <ViewStub
            android:id="@+id/viewsub"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout="@layout/view_db_viesub"
            bind:user="@{name}"
           />

    </LinearLayout>


</layout>

待加载布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="ViewSubData">


        <import type="androidx.databinding.ObservableField" />


        <variable
            name="user"
            type="String" />

        <!--        <variable-->
        <!--            name="user"-->
        <!--            type="ObservableField&lt;String&gt;" />-->

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="viewSub module" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="@{user}" />

    </LinearLayout>
</layout>

如何加载布局?

var inflatView: View? = null
if (!bind.viewsub.isInflated) {
    inflatView = bind.viewsub.viewStub?.inflate()!!
}

数据绑定:

        viewstub的数据绑定也是分为两个方法:

1.在布局中直接绑定

也是通过扩展字段映射过去,

  <ViewStub
            android:id="@+id/viewsub"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout="@layout/view_db_viesub"
            bind:user="@{name}"
           />

        这里有个问题,如果的根数据是ObservableField<String>,我们正常是需要在待加载数据也设置成ObservableField<String>,但是,在Impl数据转换的时候,数据被进行了转换,

 
 

        所以你的在待加载布局中不要单独通过ObservableField接收数据。如果你不会,处理不好,可以通过一个对象来更新。或者用下面第二种方法来处理

2、代码中绑定

我们先把待加载的布局bind出来

var subData = DataBindingUtil.bind<ViewSubData>(inflatView!!)

ViewSubData:是待加载布局data class。

inflatView:viewStub.inflate的 root

注意:待加载布局还是include的布局,都可以设置class名称,不会影响根布局class的设置

数据绑定:

1.setVariable

subData?.setVariable(BR.user, text)

2.直接设置数据

var name = ObservableField<String>()
subData?.user=name

解释:

        如果你通过代码去设置data,是支持ObservableField的类型,但是在xml布局中,就会被处理转换了。切记,如果你想单向绑定,可以通过代码来设置

setVariable介绍:

        setVariable申请的变量也会在BR中生成对标的flag字段。这个字段和Bindable是一样的,所以你也可以通过设置setVariable,指向申明的字段和对应的数据绑定也是可以的。

三、总结

这样我们就完成了include和ViewStub的介绍与使用,但是ViewStub在数据绑定的时候特别要小心,如果你排查不好xml ViewStub数据绑定,就通过代码去控制

加载完待加载的ViewStub,然后通过代码直接赋值。        

子布局和待加载的布局data都是可以有自己的class name。设置后不会影响根布局的data class的设置。

猜你喜欢

转载自blog.csdn.net/qq36246172/article/details/128235985