jetpack之数据绑定的源码解读(一)

源码版本:Android10

一、DataBinding的使用

1.1 activity_databinding_main.xml源码
<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <import type="androidx.databinding.ObservableMap" />
        <import type="androidx.databinding.ObservableArrayList" />
        <import type="com.study.jetpackstudykotlin.databinding.bean.Fields" />
        <import type="com.study.jetpackstudykotlin.databinding.bean.Teacher2" />
        <import type="android.text.TextUtils" />
        <variable
            name="user"
            type="com.study.jetpackstudykotlin.databinding.bean.User" />
        <!--        "<"要用&lt;代替 -->
        <variable
            name="studentMap"
            type="ObservableMap&lt;String,Object>" />
        <variable
            name="studentArray"
            type="ObservableArrayList&lt;Object>" />
        <variable
            name="teacher"
            type="Teacher2" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout 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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <!--
         default用于预览展示
         nameFormat进行字符串格式化:    <string name="nameFormat">Full Name: %1$s:%2$s</string>
         -->
        <Button
            android:id="@+id/tv_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@{@string/nameFormat(user.firstName, user.lastName),default=aaaa}"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_tip1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="ObservableMap:"
            android:textSize="14sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_1" />

        <TextView
            android:id="@+id/tv_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{studentMap.lastName,default=yyy}"
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_tip1" />

        <TextView
            android:id="@+id/tv_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(1 + (Integer)studentMap.age),default=111}"
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_last" />


        <TextView
            android:id="@+id/tv_tip2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="ObservableArray:"
            android:textSize="14sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_age" />

        <TextView
            android:id="@+id/tv_array_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{studentArray[Fields.LAST_NAME],default=yyy}"
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_tip2" />

        <TextView
            android:id="@+id/tv_array_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(1 + (Integer)studentArray[Fields.AGE]),default=111}"
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_array_last" />

        <TextView
            android:id="@+id/tv_tip3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Observable:"
            android:textSize="14sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_array_age" />

        <TextView
            android:id="@+id/tv_observable_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{teacher.firstName,default=yyy}"
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_tip3" />

        <TextView
            android:id="@+id/tv_observable_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:shadowColor="@color/colorAccent"
            android:shadowDy="10"
            android:shadowRadius="10"
            android:text="@{teacher.lastName,default=111}"
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_observable_last" />

        <Button
            android:id="@+id/bt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:onClick="jumpActivity"
            android:text="RecyclerView"
            app:layout_constraintTop_toBottomOf="@id/tv_observable_age" />

        <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入"
            android:text="@{teacher.lastName}"
            app:layout_constraintTop_toBottomOf="@id/bt" />

        <Button
            android:id="@+id/bt_confirm"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:text="@{teacher.lastName}"
            app:layout_constraintTop_toBottomOf="@id/et" />

        <com.study.jetpackstudykotlin.databinding.view.DefineImageView
            android:id="@+id/iv"
            imgContent="@{teacher.lastName}"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:background="@{TextUtils.isEmpty(teacher.lastName)?@color/color_enable:@color/color_unable}"
            android:elevation="2dp"
            app:layout_constraintBottom_toBottomOf="@id/bt_confirm"
            app:layout_constraintLeft_toLeftOf="@id/bt_confirm"
            app:layout_constraintRight_toRightOf="@id/bt_confirm"
            app:layout_constraintTop_toTopOf="@id/bt_confirm"
            app:showShadow="@{teacher.lastName}" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

1.2 DataBindingMainActivity源码

package com.study.jetpackstudykotlin.databinding

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableArrayMap
import com.study.jetpackstudykotlin.R
import com.study.jetpackstudykotlin.databinding.bean.Teacher2
import com.study.jetpackstudykotlin.databinding.bean.User
import kotlinx.android.synthetic.main.activity_databinding_main.*

class DataBindingMainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityDatabindingMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_databinding_main
        )
        tv_1.setOnClickListener {
            //修改binding.teacher?.lastName = "confirm",?不可少,因为binding.teacher是由java转换过来的,可能为null
            binding.teacher?.lastName = "confirm"
        }
        binding.user = User("哈哈", "嘻嘻")
        binding.studentMap = ObservableArrayMap<String, Any>().apply {
            put("firstName", "Google")
            put("lastName", "Inc.")
            put("age", 17)
        }

        binding.studentArray = ObservableArrayList<Any>().apply {
            add("Byte Dance")
            add("Inc.")
            add(888)
        }
        val teacher2 = Teacher2("李", "老师")
        binding.teacher = teacher2
        var i = 0
        Thread {
            for (j in 0..10) {
                teacher2.firstName = "${teacher2.firstName}$i"
                i++
                Thread.sleep(100)
            }
        }.start()
    }

    fun jumpActivity(view: View) {
        startActivity(Intent(this, RecyclerViewActivity::class.java))
    }
}
1.3 DefineImageView源码
package com.study.jetpackstudykotlin.databinding.view

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.widget.AppCompatImageView
import androidx.databinding.BindingMethod
import androidx.databinding.BindingMethods

@BindingMethods(
    BindingMethod(
        type = AppCompatImageView::class,
        attribute = "showShadow",
        method = "showShadow"
    )
)
class DefineImageView : AppCompatImageView {

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attributes: AttributeSet?) : this(context, attributes, 0)

    constructor(context: Context, attributes: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attributes,
        defStyleAttr
    )

    fun showShadow(content: String) {
        visibility = if (content == "confirm") View.VISIBLE else View.GONE
    }


}
1.4 ViewAdapter源码
package com.study.jetpackstudykotlin.databinding.viewAdapter;

import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.appcompat.widget.AppCompatImageView;
import androidx.databinding.BindingAdapter;
import androidx.databinding.BindingConversion;
import androidx.databinding.InverseBindingAdapter;
import androidx.databinding.InverseBindingListener;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

public class ViewAdapter {


    @BindingAdapter(value = {"imgContent"})
    public static void loadImage(AppCompatImageView imageView, final String content) {
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(v.getContext(), content, Toast.LENGTH_SHORT).show();
            }
        });
    }

    @BindingConversion
    public static ColorDrawable convertColorToDrawable(int color) {
        return new ColorDrawable(color);
    }
    
    
    //===================SwipeRefreshLayout双向绑定的具体实现===================
    @InverseBindingAdapter(attribute = "refreshing", event = "refreshingAttrChanged")
    public static boolean isRefreshing(SwipeRefreshLayout view) {
        return view.isRefreshing();
    }

    @BindingAdapter(value = {"refreshingAttrChanged"}, requireAll = false)
    public static void setOnRefreshListener(final SwipeRefreshLayout view,
                                            final InverseBindingListener refreshingAttrChanged) {

        if (refreshingAttrChanged != null) {
            view.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    refreshingAttrChanged.onChange();
                    Log.e("refresh::", "当前binding.refresh值为" + view.isRefreshing());
                }
            });
        }
    }

    @BindingAdapter("refreshing")
    public static void setRefreshing(SwipeRefreshLayout view, boolean refreshing) {
        if (refreshing != view.isRefreshing()) {
            view.setRefreshing(refreshing);
        }
    }

}

二、数据绑定的源码解析

2.1 使用DataBinding的布局文件如何转化为标准的布局文件
此处以生成activity_databinding_main.xml为例
2.1.1 生成标准activity_databinding_main.xml文件所需要的配置文件
配置文件路径:D:\Android\Space\Mine\JetpackStudyKotlin\app\build\intermediates\data_binding_layout_info_type_merge\debug\mergeDebugResources\out\activity_databinding_main-layout.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Layout layout="activity_databinding_main" modulePackage="com.study.jetpackstudykotlin" filePath="D:\Android\Space\Mine\JetpackStudyKotlin\app\src\main\res\layout\databinding\layout\activity_databinding_main.xml" directory="layout" isMerge="false">
    <Variables declared="true" type="com.study.jetpackstudykotlin.databinding.bean.User" name="user">
        <location startLine="15" startOffset="8" endLine="17" endOffset="71"/>
    </Variables>
    <Variables declared="true" type="ObservableMap&lt;String,Object&gt;" name="studentMap">
        <location startLine="19" startOffset="8" endLine="21" endOffset="52"/>
    </Variables>
    <Variables declared="true" type="ObservableArrayList&lt;Object&gt;" name="studentArray">
        <location startLine="23" startOffset="8" endLine="25" endOffset="51"/>
    </Variables>
    <Variables declared="true" type="Teacher2" name="teacher">
        <location startLine="27" startOffset="8" endLine="29" endOffset="29"/>
    </Variables>
    <Imports type="androidx.databinding.ObservableMap" name="ObservableMap">
        <location startLine="5" startOffset="8" endLine="5" endOffset="59"/>
    </Imports>
    <Imports type="androidx.databinding.ObservableArrayList" name="ObservableArrayList">
        <location startLine="7" startOffset="8" endLine="7" endOffset="65"/>
    </Imports>
    <Imports type="com.study.jetpackstudykotlin.databinding.bean.Fields" name="Fields">
        <location startLine="9" startOffset="8" endLine="9" endOffset="77"/>
    </Imports>
    <Imports type="com.study.jetpackstudykotlin.databinding.bean.Teacher2" name="Teacher2">
        <location startLine="11" startOffset="8" endLine="11" endOffset="79"/>
    </Imports>
    <Imports type="android.text.TextUtils" name="TextUtils">
        <location startLine="13" startOffset="8" endLine="13" endOffset="47"/>
    </Imports>
    <Targets>
        <Target tag="layout/activity_databinding_main_0" view="androidx.constraintlayout.widget.ConstraintLayout">
            <Expressions/>
            <location startLine="32" startOffset="4" endLine="155" endOffset="55"/>
        </Target>
        <Target id="@+id/tv_1" tag="binding_1" view="Button">
            <Expressions>
                <Expression text="@string/nameFormat(user.firstName, user.lastName),default=aaaa" attribute="android:text">
                    <Location startLine="47" startOffset="12" endLine="47" endOffset="91"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="47" startOffset="28" endLine="47" endOffset="89"/>
                </Expression>
            </Expressions>
            <location startLine="42" startOffset="8" endLine="50" endOffset="55"/>
        </Target>
		<!--include标签布局-->
        <Target id="@+id/tv_age" tag="layout/activity_databinding_main_0" include="main_include">
            <Expressions>
                <Expression text="studentMap" attribute="app:studentMap">
                    <Location startLine="57" startOffset="12" endLine="57" endOffset="41"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="57" startOffset="30" endLine="57" endOffset="39"/>
                </Expression>
            </Expressions>
            <location startLine="52" startOffset="8" endLine="59" endOffset="60"/>
        </Target>
        <Target id="@+id/tv_array_last" tag="binding_2" view="TextView">
            <Expressions>
                <Expression text="studentArray[Fields.LAST_NAME],default=yyy" attribute="android:text">
                    <Location startLine="74" startOffset="12" endLine="74" endOffset="71"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="74" startOffset="28" endLine="74" endOffset="69"/>
                </Expression>
            </Expressions>
            <location startLine="70" startOffset="8" endLine="77" endOffset="63"/>
        </Target>
        <Target id="@+id/tv_array_age" tag="binding_3" view="TextView">
            <Expressions>
                <Expression text="String.valueOf(1 + (Integer)studentArray[Fields.AGE]),default=111" attribute="android:text">
                    <Location startLine="83" startOffset="12" endLine="83" endOffset="94"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="83" startOffset="28" endLine="83" endOffset="92"/>
                </Expression>
            </Expressions>
            <location startLine="79" startOffset="8" endLine="86" endOffset="69"/>
        </Target>
        <Target id="@+id/tv_observable_last" tag="binding_4" view="TextView">
            <Expressions>
                <Expression text="teacher.firstName,default=yyy" attribute="android:text">
                    <Location startLine="101" startOffset="12" endLine="101" endOffset="58"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="101" startOffset="28" endLine="101" endOffset="56"/>
                </Expression>
            </Expressions>
            <location startLine="97" startOffset="8" endLine="104" endOffset="63"/>
        </Target>
        <Target id="@+id/tv_observable_age" tag="binding_5" view="TextView">
            <Expressions>
                <Expression text="teacher.lastName,default=111" attribute="android:text">
                    <Location startLine="113" startOffset="12" endLine="113" endOffset="57"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="113" startOffset="28" endLine="113" endOffset="55"/>
                </Expression>
            </Expressions>
            <location startLine="106" startOffset="8" endLine="116" endOffset="74"/>
        </Target>
        <Target id="@+id/et" tag="binding_6" view="EditText">
            <Expressions>
                <Expression text="teacher.lastName" attribute="android:text">
                    <Location startLine="132" startOffset="12" endLine="132" endOffset="45"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="132" startOffset="28" endLine="132" endOffset="43"/>
                </Expression>
            </Expressions>
            <location startLine="127" startOffset="8" endLine="133" endOffset="58"/>
        </Target>
        <Target id="@+id/bt_confirm" tag="binding_7" view="Button">
            <Expressions>
                <Expression text="teacher.lastName" attribute="android:text">
                    <Location startLine="139" startOffset="12" endLine="139" endOffset="45"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="139" startOffset="28" endLine="139" endOffset="43"/>
                </Expression>
            </Expressions>
            <location startLine="135" startOffset="8" endLine="140" endOffset="58"/>
        </Target>
        <Target id="@+id/iv" tag="binding_8" view="com.study.jetpackstudykotlin.databinding.view.DefineImageView">
            <Expressions>
                <Expression text="teacher.lastName" attribute="imgContent">
                    <Location startLine="144" startOffset="12" endLine="144" endOffset="43"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="144" startOffset="26" endLine="144" endOffset="41"/>
                </Expression>
                <Expression text="TextUtils.isEmpty(teacher.lastName)?@color/color_enable:@color/color_unable" attribute="android:background">
                    <Location startLine="147" startOffset="12" endLine="147" endOffset="110"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="147" startOffset="34" endLine="147" endOffset="108"/>
                </Expression>
                <Expression text="teacher.lastName" attribute="app:showShadow">
                    <Location startLine="153" startOffset="12" endLine="153" endOffset="47"/>
                    <TwoWay>false</TwoWay>
                    <ValueLocation startLine="153" startOffset="30" endLine="153" endOffset="45"/>
                </Expression>
            </Expressions>
            <location startLine="142" startOffset="8" endLine="153" endOffset="50"/>
        </Target>
        <Target id="@+id/tv_tip2" view="TextView">
            <Expressions/>
            <location startLine="61" startOffset="8" endLine="68" endOffset="62"/>
        </Target>
        <Target id="@+id/tv_tip3" view="TextView">
            <Expressions/>
            <location startLine="88" startOffset="8" endLine="95" endOffset="68"/>
        </Target>
        <Target id="@+id/bt" view="Button">
            <Expressions/>
            <location startLine="118" startOffset="8" endLine="125" endOffset="73"/>
        </Target>
    </Targets>
</Layout>
2.1.2 标准activity_databinding_main.xml文件
文件路径:D:\Android\Space\Mine\JetpackStudyKotlin\app\build\intermediates\incremental\mergeDebugResources\stripped.dir\layout\activity_databinding_main.xml
<?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" android:tag="layout/activity_databinding_main_0">
        <!--
         default用于预览展示
         nameFormat进行字符串格式化:    <string name="nameFormat">Full Name: %1$s:%2$s</string>
         -->
        <Button
            android:id="@+id/tv_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="aaaa"                                                             
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"  android:tag="binding_1"/>

		<!--使用include布局,要想layout的属性生效,必须重写android:layout_width和android:layout_height-->
        <include
            android:id="@+id/tv_age"
            layout="@layout/main_include"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
                                          
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_1" />

		
        <TextView
            android:id="@+id/tv_tip2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="ObservableArray:"
            android:textSize="14sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_age" />

        <TextView
            android:id="@+id/tv_array_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="yyy"                                          
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_tip2"  android:tag="binding_2"/>

        <TextView
            android:id="@+id/tv_array_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="111"                                                                 
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_array_last"  android:tag="binding_3"/>

        <TextView
            android:id="@+id/tv_tip3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Observable:"
            android:textSize="14sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_array_age" />

        <TextView
            android:id="@+id/tv_observable_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="yyy"                             
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_tip3"  android:tag="binding_4"/>

        <TextView
            android:id="@+id/tv_observable_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:shadowColor="@color/colorAccent"
            android:shadowDy="10"
            android:shadowRadius="10"
            android:text="111"                            
            android:textSize="20sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_observable_last"  android:tag="binding_5"/>

        <Button
            android:id="@+id/bt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:onClick="jumpActivity"
            android:text="RecyclerView"
            app:layout_constraintTop_toBottomOf="@id/tv_observable_age" />

        <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入"
            android:tag="binding_6"           
            app:layout_constraintTop_toBottomOf="@id/bt" />

        <Button
            android:id="@+id/bt_confirm"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:tag="binding_7"           
            app:layout_constraintTop_toBottomOf="@id/et" />

        <com.study.jetpackstudykotlin.databinding.view.DefineImageView
            android:id="@+id/iv"
            android:tag="binding_8"         
            android:layout_width="match_parent"
            android:layout_height="45dp"                                                                                  
            android:elevation="2dp"
            app:layout_constraintBottom_toBottomOf="@id/bt_confirm"
            app:layout_constraintLeft_toLeftOf="@id/bt_confirm"
            app:layout_constraintRight_toRightOf="@id/bt_confirm"
            app:layout_constraintTop_toTopOf="@id/bt_confirm"
                                                 />

    </androidx.constraintlayout.widget.ConstraintLayout>
         
         
2.2 DataBindingUtil源码
DataBindingUtil加载时,下列对象将会被加载至内存中:
    private static DataBinderMapper sMapper = new DataBinderMapperImpl();

此处DataBinderMapperImpl是由编译生成,DataBinderMapperImpl源码路径如下:
D:\Android\Space\Mine\JetpackStudyKotlin\app\build\generated\ap_generated_sources\debug\out\androidx\databinding\DataBinderMapperImpl.java
源码如下所示:

package androidx.databinding;

public class DataBinderMapperImpl extends MergedDataBinderMapper {
  DataBinderMapperImpl() {
  	//添加用户自己报名下面DataBinderMapperImpl类,该类的路径D:\Android\Space\Mine\JetpackStudyKotlin\app\
  	//build\generated\ap_generated_sources\debug\out\com\study\jetpackstudykotlin\DataBinderMapperImpl.java
    addMapper(new com.study.jetpackstudykotlin.DataBinderMapperImpl());
  }
}

D:\Android\Space\Mine\JetpackStudyKotlin\app\build\generated\ap_generated_sources\debug\out\com\study\jetpackstudykotlin\DataBinderMapperImpl.java的源码如下所示:

package com.study.jetpackstudykotlin;

import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.View;

import androidx.databinding.DataBinderMapper;
import androidx.databinding.DataBindingComponent;
import androidx.databinding.ViewDataBinding;

import com.study.jetpackstudykotlin.databinding.ActivityDatabindingMainBindingImpl;
import com.study.jetpackstudykotlin.databinding.ActivityRecyclerViewBindingImpl;
import com.study.jetpackstudykotlin.databinding.ItemRecyclerBindingImpl;
import com.study.jetpackstudykotlin.databinding.MainIncludeBindingImpl;

import java.lang.IllegalArgumentException;
import java.lang.Integer;
import java.lang.Object;
import java.lang.Override;
import java.lang.RuntimeException;
import java.lang.String;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class DataBinderMapperImpl extends DataBinderMapper {
    private static final int LAYOUT_ACTIVITYDATABINDINGMAIN = 1;

    private static final int LAYOUT_ACTIVITYRECYCLERVIEW = 2;

    private static final int LAYOUT_ITEMRECYCLER = 3;

    private static final int LAYOUT_MAININCLUDE = 4;

    private static final SparseIntArray INTERNAL_LAYOUT_ID_LOOKUP = new SparseIntArray(4);

    static {
        INTERNAL_LAYOUT_ID_LOOKUP.put(com.study.jetpackstudykotlin.R.layout.activity_databinding_main, LAYOUT_ACTIVITYDATABINDINGMAIN);
        INTERNAL_LAYOUT_ID_LOOKUP.put(com.study.jetpackstudykotlin.R.layout.activity_recycler_view, LAYOUT_ACTIVITYRECYCLERVIEW);
        INTERNAL_LAYOUT_ID_LOOKUP.put(com.study.jetpackstudykotlin.R.layout.item_recycler, LAYOUT_ITEMRECYCLER);
        INTERNAL_LAYOUT_ID_LOOKUP.put(com.study.jetpackstudykotlin.R.layout.main_include, LAYOUT_MAININCLUDE);
    }

    @Override
    public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) {
        int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
        if (localizedLayoutId > 0) {
            final Object tag = view.getTag();
            if (tag == null) {
                throw new RuntimeException("view must have a tag");
            }
            //根据不同标记返回不同的Binding实现类
            switch (localizedLayoutId) {
                case LAYOUT_ACTIVITYDATABINDINGMAIN: {
                    if ("layout/activity_databinding_main_0".equals(tag)) {
                        return new ActivityDatabindingMainBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for activity_databinding_main is invalid. Received: " + tag);
                }
                case LAYOUT_ACTIVITYRECYCLERVIEW: {
                    if ("layout/activity_recycler_view_0".equals(tag)) {
                        return new ActivityRecyclerViewBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for activity_recycler_view is invalid. Received: " + tag);
                }
                case LAYOUT_ITEMRECYCLER: {
                    if ("layout/item_recycler_0".equals(tag)) {
                        return new ItemRecyclerBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for item_recycler is invalid. Received: " + tag);
                }
                case LAYOUT_MAININCLUDE: {
                    if ("layout/main_include_0".equals(tag)) {
                        return new MainIncludeBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for main_include is invalid. Received: " + tag);
                }
            }
        }
        return null;
    }

    @Override
    public ViewDataBinding getDataBinder(DataBindingComponent component, View[] views, int layoutId) {
        if (views == null || views.length == 0) {
            return null;
        }
        int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
        if (localizedLayoutId > 0) {
            final Object tag = views[0].getTag();
            if (tag == null) {
                throw new RuntimeException("view must have a tag");
            }
            switch (localizedLayoutId) {
            }
        }
        return null;
    }

    @Override
    public int getLayoutId(String tag) {
        if (tag == null) {
            return 0;
        }
        Integer tmpVal = InnerLayoutIdLookup.sKeys.get(tag);
        return tmpVal == null ? 0 : tmpVal;
    }

    @Override
    public String convertBrIdToString(int localId) {
        String tmpVal = InnerBrLookup.sKeys.get(localId);
        return tmpVal;
    }

    @Override
    public List<DataBinderMapper> collectDependencies() {
        ArrayList<DataBinderMapper> result = new ArrayList<DataBinderMapper>(1);
        result.add(new androidx.databinding.library.baseAdapters.DataBinderMapperImpl());
        return result;
    }

    private static class InnerBrLookup {
        static final SparseArray<String> sKeys = new SparseArray<String>(9);

        static {
            sKeys.put(0, "_all");
            sKeys.put(1, "firstName");
            sKeys.put(2, "lastName");
            sKeys.put(3, "teacher");
            sKeys.put(4, "studentArray");
            sKeys.put(5, "studentMap");
            sKeys.put(6, "refresh");
            sKeys.put(7, "user");
        }
    }

    private static class InnerLayoutIdLookup {
        static final HashMap<String, Integer> sKeys = new HashMap<String, Integer>(4);

        static {
            sKeys.put("layout/activity_databinding_main_0", com.study.jetpackstudykotlin.R.layout.activity_databinding_main);
            sKeys.put("layout/activity_recycler_view_0", com.study.jetpackstudykotlin.R.layout.activity_recycler_view);
            sKeys.put("layout/item_recycler_0", com.study.jetpackstudykotlin.R.layout.item_recycler);
            sKeys.put("layout/main_include_0", com.study.jetpackstudykotlin.R.layout.main_include);
        }
    }
}

上诉中addMapper方法源码如下所示:

 //给mMapper添加数据
    @SuppressWarnings("WeakerAccess")
    public void addMapper(DataBinderMapper mapper) {
        Class<? extends DataBinderMapper> mapperClass = mapper.getClass();
        if (mExistingMappers.add(mapperClass)) {
            mMappers.add(mapper);
            final List<DataBinderMapper> dependencies = mapper.collectDependencies();
            for(DataBinderMapper dependency : dependencies) {
                addMapper(dependency);
            }
        }
    } 

DataBindingUtil.setContentView( this, R.layout.activity_databinding_main)源码如下所示:

 public static <T extends ViewDataBinding> T setContentView(@NonNull Activity activity,
            int layoutId) {
        return setContentView(activity, layoutId, sDefaultComponent);
 }

public static <T extends ViewDataBinding> T setContentView(@NonNull Activity activity,
            int layoutId, @Nullable DataBindingComponent bindingComponent) {
        activity.setContentView(layoutId);
        View decorView = activity.getWindow().getDecorView();
        ViewGroup contentView = (ViewGroup) decorView.findViewById(android.R.id.content);
        return bindToAddedViews(bindingComponent, contentView, 0, layoutId);
}

private static <T extends ViewDataBinding> T bindToAddedViews(DataBindingComponent component,
            ViewGroup parent, int startChildren, int layoutId) {
        final int endChildren = parent.getChildCount();
        final int childrenAdded = endChildren - startChildren;
          //ActivityDataBindingMain中的childrenAdded=1 
        if (childrenAdded == 1) {
            final View childView = parent.getChildAt(endChildren - 1);
            return bind(component, childView, layoutId);
        } else {
            final View[] children = new View[childrenAdded];
            for (int i = 0; i < childrenAdded; i++) {
                children[i] = parent.getChildAt(i + startChildren);
            }
            return bind(component, children, layoutId);
        }
    }

static <T extends ViewDataBinding> T bind(DataBindingComponent bindingComponent, View root,
            int layoutId) {
            //此处sMapper是D:\Android\Space\Mine\JetpackStudyKotlin\app\build\generated\ap_generated_sources\debug\out\androidx\databinding\DataBinderMapperImpl.java
        return (T) sMapper.getDataBinder(bindingComponent, root, layoutId);
}

上述sMapper.getDataBinder的源码如下:

 @Override
    public ViewDataBinding getDataBinder(DataBindingComponent bindingComponent, View view,
            int layoutId) {
        //因为mMappers中的元素类型[com.study.jetpackstudykotlin.DataBinderMapperImpl,androidx.databinding.DataBinderMapperImpl]    
        for(DataBinderMapper mapper : mMappers) {
            ViewDataBinding result = mapper.getDataBinder(bindingComponent, view, layoutId);
            if (result != null) {
                return result;
            }
        }
        if (loadFeatures()) {
            return getDataBinder(bindingComponent, view, layoutId);
        }
        return null;
    }

上述mapper.getDataBinder(bindingComponent, view, layoutId)实质调用com.study.jetpackstudykotlin.DataBinderMapperImpl中如下方法:

    @Override
    public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) {
        int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
        if (localizedLayoutId > 0) {
            final Object tag = view.getTag();
            if (tag == null) {
                throw new RuntimeException("view must have a tag");
            }
            switch (localizedLayoutId) {
                case LAYOUT_ACTIVITYDATABINDINGMAIN: {
                    if ("layout/activity_databinding_main_0".equals(tag)) {
                        return new ActivityDatabindingMainBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for activity_databinding_main is invalid. Received: " + tag);
                }
                case LAYOUT_ACTIVITYRECYCLERVIEW: {
                    if ("layout/activity_recycler_view_0".equals(tag)) {
                        return new ActivityRecyclerViewBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for activity_recycler_view is invalid. Received: " + tag);
                }
                case LAYOUT_ITEMRECYCLER: {
                    if ("layout/item_recycler_0".equals(tag)) {
                        return new ItemRecyclerBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for item_recycler is invalid. Received: " + tag);
                }
                case LAYOUT_MAININCLUDE: {
                    if ("layout/main_include_0".equals(tag)) {
                        return new MainIncludeBindingImpl(component, view);
                    }
                    throw new IllegalArgumentException("The tag for main_include is invalid. Received: " + tag);
                }
            }
        }
        return null;
    }

com.study.jetpackstudykotlin.databinding.ActivityDatabindingMainBindingImpl源码如下:

package com.study.jetpackstudykotlin.databinding;
import com.study.jetpackstudykotlin.R;
import com.study.jetpackstudykotlin.BR;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.View;
@SuppressWarnings("unchecked")
public class ActivityDatabindingMainBindingImpl extends ActivityDatabindingMainBinding  {

    @Nullable
    private static final androidx.databinding.ViewDataBinding.IncludedLayouts sIncludes;
    @Nullable
    private static final android.util.SparseIntArray sViewsWithIds;
    static {
        //这里存储的是布局中使用include标签的布局
        sIncludes = new androidx.databinding.ViewDataBinding.IncludedLayouts(13);
        sIncludes.setIncludes(0, 
            new String[] {"main_include"},
            new int[] {9},
            new int[] {com.study.jetpackstudykotlin.R.layout.main_include});
        sViewsWithIds = new android.util.SparseIntArray();
        //这里存储的是没有使用DataBinding表达式的控件id
        sViewsWithIds.put(R.id.tv_tip2, 10);
        sViewsWithIds.put(R.id.tv_tip3, 11);
        sViewsWithIds.put(R.id.bt, 12);
    }
    // views
    @NonNull
    private final androidx.constraintlayout.widget.ConstraintLayout mboundView0;
    

    public ActivityDatabindingMainBindingImpl(@Nullable androidx.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
        //mapBindings解析布局中的控件
        this(bindingComponent, root, mapBindings(bindingComponent, root, 13, sIncludes, sViewsWithIds));
    }
    private ActivityDatabindingMainBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
        super(bindingComponent, root, 4
            , (android.widget.Button) bindings[12]
            , (android.widget.Button) bindings[7]
            , (android.widget.EditText) bindings[6]
            , (com.study.jetpackstudykotlin.databinding.view.DefineImageView) bindings[8]
            , (android.widget.Button) bindings[1]
            , (com.study.jetpackstudykotlin.databinding.MainIncludeBinding) bindings[9]
            , (android.widget.TextView) bindings[3]
            , (android.widget.TextView) bindings[2]
            , (android.widget.TextView) bindings[5]
            , (android.widget.TextView) bindings[4]
            , (android.widget.TextView) bindings[10]
            , (android.widget.TextView) bindings[11]
            );
        this.btConfirm.setTag(null);
        this.et.setTag(null);
        this.iv.setTag(null);
        this.mboundView0 = (androidx.constraintlayout.widget.ConstraintLayout) bindings[0];
        this.mboundView0.setTag(null);
        this.tv1.setTag(null);
        this.tvArrayAge.setTag(null);
        this.tvArrayLast.setTag(null);
        this.tvObservableAge.setTag(null);
        this.tvObservableLast.setTag(null);
        setRootTag(root);
        // listeners
        invalidateAll();
    }

    @Override
    public void invalidateAll() {
        synchronized(this) {
                mDirtyFlags = 0x80L;
        }
        tvAge.invalidateAll();
        //调用父类方法,发送回调事件
        requestRebind();
    }

    @Override
    public boolean hasPendingBindings() {
        synchronized(this) {
            if (mDirtyFlags != 0) {
                return true;
            }
        }
        if (tvAge.hasPendingBindings()) {
            return true;
        }
        return false;
    }

    @Override
    public boolean setVariable(int variableId, @Nullable Object variable)  {
        boolean variableSet = true;
        if (BR.studentMap == variableId) {
            setStudentMap((androidx.databinding.ObservableMap<java.lang.String,java.lang.Object>) variable);
        }
        else if (BR.teacher == variableId) {
            setTeacher((com.study.jetpackstudykotlin.databinding.bean.Teacher2) variable);
        }
        else if (BR.user == variableId) {
            setUser((com.study.jetpackstudykotlin.databinding.bean.User) variable);
        }
        else if (BR.studentArray == variableId) {
            setStudentArray((androidx.databinding.ObservableArrayList<java.lang.Object>) variable);
        }
        else {
            variableSet = false;
        }
            return variableSet;
    }

    public void setStudentMap(@Nullable androidx.databinding.ObservableMap<java.lang.String,java.lang.Object> StudentMap) {
        updateRegistration(0, StudentMap);
        this.mStudentMap = StudentMap;
        synchronized(this) {
            mDirtyFlags |= 0x1L;
        }
        //通知属性改变
        notifyPropertyChanged(BR.studentMap);
        super.requestRebind();
    }
    public void setTeacher(@Nullable com.study.jetpackstudykotlin.databinding.bean.Teacher2 Teacher) {
        updateRegistration(1, Teacher);
        this.mTeacher = Teacher;
        synchronized(this) {
            mDirtyFlags |= 0x2L;
        }
          //通知属性改变
        notifyPropertyChanged(BR.teacher);
        super.requestRebind();
    }
    public void setUser(@Nullable com.study.jetpackstudykotlin.databinding.bean.User User) {
        //User为什么没有调用updateRegistration方法呢?因为User类是不被观察的
        this.mUser = User;
        synchronized(this) {
            mDirtyFlags |= 0x10L;
        }
        notifyPropertyChanged(BR.user);
        super.requestRebind();
    }
    public void setStudentArray(@Nullable androidx.databinding.ObservableArrayList<java.lang.Object> StudentArray) {
        updateRegistration(2, StudentArray);
        this.mStudentArray = StudentArray;
        synchronized(this) {
            mDirtyFlags |= 0x4L;
        }
          //通知属性改变
        notifyPropertyChanged(BR.studentArray);
        super.requestRebind();
    }

    @Override
    public void setLifecycleOwner(@Nullable androidx.lifecycle.LifecycleOwner lifecycleOwner) {
        super.setLifecycleOwner(lifecycleOwner);
        tvAge.setLifecycleOwner(lifecycleOwner);
    }

    //监听字段变化
    @Override
    protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
        switch (localFieldId) {
            case 0 :
                return onChangeStudentMap((androidx.databinding.ObservableMap<java.lang.String,java.lang.Object>) object, fieldId);
            case 1 :
                return onChangeTeacher((com.study.jetpackstudykotlin.databinding.bean.Teacher2) object, fieldId);
            case 2 :
                return onChangeStudentArray((androidx.databinding.ObservableArrayList<java.lang.Object>) object, fieldId);
            case 3 :
                return onChangeTvAge((com.study.jetpackstudykotlin.databinding.MainIncludeBinding) object, fieldId);
        }
        return false;
    }
    private boolean onChangeStudentMap(androidx.databinding.ObservableMap<java.lang.String,java.lang.Object> StudentMap, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    mDirtyFlags |= 0x1L;
            }
            return true;
        }
        return false;
    }
    private boolean onChangeTeacher(com.study.jetpackstudykotlin.databinding.bean.Teacher2 Teacher, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    mDirtyFlags |= 0x2L;
            }
            return true;
        }
        else if (fieldId == BR.firstName) {
            synchronized(this) {
                    mDirtyFlags |= 0x20L;
            }
            return true;
        }
        else if (fieldId == BR.lastName) {
            synchronized(this) {
                    mDirtyFlags |= 0x40L;
            }
            return true;
        }
        return false;
    }
    private boolean onChangeStudentArray(androidx.databinding.ObservableArrayList<java.lang.Object> StudentArray, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    mDirtyFlags |= 0x4L;
            }
            return true;
        }
        return false;
    }
    private boolean onChangeTvAge(com.study.jetpackstudykotlin.databinding.MainIncludeBinding TvAge, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    mDirtyFlags |= 0x8L;
            }
            return true;
        }
        return false;
    }

	//最终对控件的赋值实在此处完成的
    @Override
    protected void executeBindings() {
        long dirtyFlags = 0;
        synchronized(this) {
            dirtyFlags = mDirtyFlags;
            mDirtyFlags = 0;
        }
        int androidxDatabindingViewDataBindingSafeUnboxIntegerStudentArrayFieldsAGE = 0;
        java.lang.Object studentArrayFieldsLASTNAME = null;
        java.lang.String teacherFirstName = null;
        androidx.databinding.ObservableMap<java.lang.String,java.lang.Object> studentMap = mStudentMap;
        java.lang.Object studentArrayFieldsAGE = null;
        java.lang.String stringValueOfInt1IntegerStudentArrayFieldsAGE = null;
        com.study.jetpackstudykotlin.databinding.bean.Teacher2 teacher = mTeacher;
        java.lang.String userFirstName = null;
        com.study.jetpackstudykotlin.databinding.bean.User user = mUser;
        java.lang.String userLastName = null;
        java.lang.Integer integerStudentArrayFieldsAGE = null;
        java.lang.String tv1AndroidStringNameFormatUserFirstNameUserLastName = null;
        int textUtilsIsEmptyTeacherLastNameIvAndroidColorColorEnableIvAndroidColorColorUnable = 0;
        androidx.databinding.ObservableArrayList<java.lang.Object> studentArray = mStudentArray;
        java.lang.String teacherLastName = null;
        int int1IntegerStudentArrayFieldsAGE = 0;
        boolean textUtilsIsEmptyTeacherLastName = false;

        if ((dirtyFlags & 0x81L) != 0) {
        }
        if ((dirtyFlags & 0xe2L) != 0) {


            if ((dirtyFlags & 0xa2L) != 0) {

                    if (teacher != null) {
                        // read teacher.firstName
                        teacherFirstName = teacher.getFirstName();
                    }
            }
            if ((dirtyFlags & 0xc2L) != 0) {

                    if (teacher != null) {
                        // read teacher.lastName
                        teacherLastName = teacher.getLastName();
                    }


                    // read TextUtils.isEmpty(teacher.lastName)
                    textUtilsIsEmptyTeacherLastName = android.text.TextUtils.isEmpty(teacherLastName);
                if((dirtyFlags & 0xc2L) != 0) {
                    if(textUtilsIsEmptyTeacherLastName) {
                            dirtyFlags |= 0x200L;
                    }
                    else {
                            dirtyFlags |= 0x100L;
                    }
                }


                    // read TextUtils.isEmpty(teacher.lastName) ? @android:color/color_enable : @android:color/color_unable
                    textUtilsIsEmptyTeacherLastNameIvAndroidColorColorEnableIvAndroidColorColorUnable = ((textUtilsIsEmptyTeacherLastName) ? (getColorFromResource(iv, R.color.color_enable)) : (getColorFromResource(iv, R.color.color_unable)));
            }
        }
        if ((dirtyFlags & 0x90L) != 0) {



                if (user != null) {
                    // read user.firstName
                    userFirstName = user.getFirstName();
                    // read user.lastName
                    userLastName = user.getLastName();
                }


                // read @android:string/nameFormat
                tv1AndroidStringNameFormatUserFirstNameUserLastName = tv1.getResources().getString(R.string.nameFormat, userFirstName, userLastName);
        }
        if ((dirtyFlags & 0x84L) != 0) {



                if (studentArray != null) {
                    // read studentArray[Fields.LAST_NAME]
                    studentArrayFieldsLASTNAME = getFromList(studentArray, com.study.jetpackstudykotlin.databinding.bean.Fields.LAST_NAME);
                    // read studentArray[Fields.AGE]
                    studentArrayFieldsAGE = getFromList(studentArray, com.study.jetpackstudykotlin.databinding.bean.Fields.AGE);
                }


                if (studentArrayFieldsAGE != null) {
                    // read (Integer) studentArray[Fields.AGE]
                    integerStudentArrayFieldsAGE = ((java.lang.Integer) (studentArrayFieldsAGE));
                }


                // read androidx.databinding.ViewDataBinding.safeUnbox((Integer) studentArray[Fields.AGE])
                androidxDatabindingViewDataBindingSafeUnboxIntegerStudentArrayFieldsAGE = androidx.databinding.ViewDataBinding.safeUnbox(integerStudentArrayFieldsAGE);


                // read (1) + (androidx.databinding.ViewDataBinding.safeUnbox((Integer) studentArray[Fields.AGE]))
                int1IntegerStudentArrayFieldsAGE = (1) + (androidxDatabindingViewDataBindingSafeUnboxIntegerStudentArrayFieldsAGE);


                // read String.valueOf((1) + (androidx.databinding.ViewDataBinding.safeUnbox((Integer) studentArray[Fields.AGE])))
                stringValueOfInt1IntegerStudentArrayFieldsAGE = java.lang.String.valueOf(int1IntegerStudentArrayFieldsAGE);
        }
        // batch finished
        if ((dirtyFlags & 0xc2L) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.btConfirm, teacherLastName);
            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.et, teacherLastName);
            //@BindingAdapter(loadImage)在此处使用
            com.study.jetpackstudykotlin.databinding.viewAdapter.ViewAdapter.loadImage(this.iv, teacherLastName);
            //@BindingConversion在此处使用
            androidx.databinding.adapters.ViewBindingAdapter.setBackground(this.iv, com.study.jetpackstudykotlin.databinding.viewAdapter.ViewAdapter.convertColorToDrawable(textUtilsIsEmptyTeacherLastNameIvAndroidColorColorEnableIvAndroidColorColorUnable));
            //@BindingMethod在此使用
            this.iv.showShadow(teacherLastName);
            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.tvObservableAge, teacherLastName);
        }
        if ((dirtyFlags & 0x90L) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.tv1, tv1AndroidStringNameFormatUserFirstNameUserLastName);
        }
        if ((dirtyFlags & 0x81L) != 0) {
            // api target 1

            this.tvAge.setStudentMap(studentMap);
        }
        if ((dirtyFlags & 0x84L) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.tvArrayAge, stringValueOfInt1IntegerStudentArrayFieldsAGE);
            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.tvArrayLast, (java.lang.CharSequence) studentArrayFieldsLASTNAME);
        }
        if ((dirtyFlags & 0xa2L) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.tvObservableLast, teacherFirstName);
        }
        executeBindingsOn(tvAge);
    }

    // 数据标记值
    private  long mDirtyFlags = 0xffffffffffffffffL;
    /* flag mapping
        flag 0 (0x1L): studentMap
        flag 1 (0x2L): teacher
        flag 2 (0x3L): studentArray
        flag 3 (0x4L): tvAge
        flag 4 (0x5L): user
        flag 5 (0x6L): teacher.firstName
        flag 6 (0x7L): teacher.lastName
        flag 7 (0x8L): null
        flag 8 (0x9L): TextUtils.isEmpty(teacher.lastName) ? @android:color/color_enable : @android:color/color_unable
        flag 9 (0xaL): TextUtils.isEmpty(teacher.lastName) ? @android:color/color_enable : @android:color/color_unable
    flag mapping end*/
    //end
}

三、总结

这里只介绍了关于DataBinding是如何实现数据绑定,以及被绑定的View是如何被赋值的。关于@InverseBindingAdapter以及如何实现双向绑定将在下一篇文章中介绍。

DataBinding时序图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为AI助手,我无法直接安装nvidia-jetpack,但是我可以为您提供一些步骤,帮助您完成源码安装nvidia-jetpack的过程。 1.下载nvidia-jetpack源码 您可以从官方网站下载nvidia-jetpack源码包,下载后解压到本地目录。 2.安装依赖包 在安装nvidia-jetpack前,您需要安装一些必要的依赖包,可以使用以下命令安装: ``` sudo apt-get update sudo apt-get install build-essential cmake git unzip pkg-config sudo apt-get install libjpeg-dev libpng-dev libtiff-dev sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev sudo apt-get install libxvidcore-dev libx264-dev sudo apt-get install libgtk-3-dev sudo apt-get install libatlas-base-dev gfortran ``` 3.安装CUDA 由于nvidia-jetpack需要CUDA支持,因此您需要先安装CUDA。您可以从nvidia官网下载相应的CUDA版本并按照官方指南进行安装。 4.安装cuDNN 同样,您需要安装cuDNN以支持nvidia-jetpack,您可以从nvidia官网下载相应的cuDNN版本并按照官方指南进行安装。 5.编译nvidia-jetpack 打开终端,进入nvidia-jetpack源码目录,执行以下命令: ``` mkdir build cd build cmake .. make -j4 ``` 其中-j4表示使用4个线程进行编译,可以根据您的CPU核心数进行调整。 6.安装nvidia-jetpack 编译成功后,执行以下命令进行安装: ``` sudo make install ``` 安装完成后,您可以执行以下命令进行验证: ``` jetson_release -v ``` 如果输出了正确的版本信息,则表示安装成功。 希望这些步骤能够帮助到您。请注意,由于nvidia-jetpack的安装过程较为复杂,如果您不熟悉Linux操作,请谨慎操作,以免造成不必要的损失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值