Android?DataBinding類關(guān)系深入探究
一、在相應的板塊中開啟DataBinding
dataBinding {
enabled true
}
二、DataBing的簡單使用
這里寫一個簡單的布局,如下:
<?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">
<TextView
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
android:text="Alice"
android:textColor="#333333"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@id/second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bob"
android:textColor="#999"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/first" />
</androidx.constraintlayout.widget.ConstraintLayout>沒錯,就是一個包含兩個TextView的布局,雖然簡單,但是也能說明DataBinding的原理;但是按照DataBinding對布局的要求,這并不符合它的要求,所以需要改成如下:
<?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="viewModel"
type="com.zfang.databindingstudy.module.SimpleViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
android:text="@{viewModel.first}"
android:textColor="#333333"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@id/second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.second}"
android:textColor="#999"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/first" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>仔細觀察下變動,兩個方面:
1、最外層多了一個layout
2、TextView的賦值使用表達式@{viewModel.xxx}來完成。
然后在Activity中如下使用生成的類:
class MainActivity : AppCompatActivity() {
private val viewModel: SimpleViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.lifecycleOwner = this
binding.viewModel = viewModel
}
}相應的ViewModel類如下:
class SimpleViewModel: ViewModel() {
private val _first = MutableLiveData("Alice")
private val _second = MutableLiveData("Bob")
val first: LiveData<String> = _first
val second: LiveData<String> = _second
}運行應用出來的結(jié)果正在預料之中,這里就不貼圖國;可能你會好奇,DataBinding是如何把數(shù)據(jù)和布局自動綁定的呢?下面就來解密下是怎么回事。
三、生成的xml布局
在Activity中使用的布局名稱是activity_main,生存的輔助類的名字為ActivityMainBinding,這里的ActivityMainBinding是我們直接能夠使用到的類,其實除了這個輔助類,還生存了另外兩個輔助xml文件,只是我們在代碼中使用不到而已。
生存的第一個布局文件內(nèi)容如下(路徑:DataBindingStudy\app\build\intermediates\incremental\debug\mergeDebugResources\stripped.dir\layout\activity_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"
android:tag="layout/activity_main_0"
tools:context=".MainActivity">
<TextView
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
android:tag="binding_1"
android:textColor="#333333"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@id/second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="binding_2"
android:textColor="#999"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/first" />
</androidx.constraintlayout.widget.ConstraintLayout>看到?jīng)],這正是Android原生的布局的文件(在我們之前寫的布局的基礎(chǔ)上去掉了layout標簽),只是做了點變動;多了一個tag屬性,這里看不出這個屬性是干什么用的,但后面我們會知道他的作用。
生存的第二個xml文件如下(路徑:DataBindingStudy\app\build\intermediates\data_binding_layout_info_type_merge\debug\out\activity_main-layout.xml):
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Layout directory="layout" filePath="app\src\main\res\layout\activity_main.xml"
isBindingData="true" isMerge="false" layout="activity_main"
modulePackage="com.zfang.databindingstudy" rootNodeType="androidx.constraintlayout.widget.ConstraintLayout">
<Variables name="viewModel" declared="true"
type="com.zfang.databindingstudy.module.SimpleViewModel">
<location endLine="8" endOffset="70" startLine="6" startOffset="8" />
</Variables>
<Targets>
<Target tag="layout/activity_main_0"
view="androidx.constraintlayout.widget.ConstraintLayout">
<Expressions />
<location endLine="41" endOffset="55" startLine="11" startOffset="4" />
</Target>
<Target id="@+id/first" tag="binding_1" view="TextView">
<Expressions>
<Expression attribute="android:text" text="viewModel.first">
<Location endLine="21" endOffset="44" startLine="21" startOffset="12" />
<TwoWay>false</TwoWay>
<ValueLocation endLine="21" endOffset="42" startLine="21" startOffset="28" />
</Expression>
</Expressions>
<location endLine="28" endOffset="63" startLine="16" startOffset="8" />
</Target>
<Target id="@+id/second" tag="binding_2" view="TextView">
<Expressions>
<Expression attribute="android:text" text="viewModel.second">
<Location endLine="34" endOffset="45" startLine="34" startOffset="12" />
<TwoWay>false</TwoWay>
<ValueLocation endLine="34" endOffset="43" startLine="34" startOffset="28" />
</Expression>
</Expressions>
<location endLine="40" endOffset="61" startLine="30" startOffset="8" />
</Target>
</Targets>
</Layout>這個文件就是基于前面的布局文件解析生存而來,里面的元素分別對應到我們布局文件里面的兩個TextView,這里拿最后一個元素說下,如下:
<Target id="@+id/second" tag="binding_2" view="TextView">
<Expressions>
<Expression attribute="android:text" text="viewModel.second">
<Location endLine="34" endOffset="45" startLine="34" startOffset="12" />
<TwoWay>false</TwoWay>
<ValueLocation endLine="34" endOffset="43" startLine="34" startOffset="28" />
</Expression>
</Expressions>
<location endLine="40" endOffset="61" startLine="30" startOffset="8" />
</Target>Target里面的id就是布局里面的id,tag就是布局里面的tag,view代表了View的類型。在Expression里面的text屬性就代表了需要執(zhí)行的表達式,里面還有個屬性TwoWay,代表是不是雙向綁定,當然這里不是雙向綁定,所以為false。
四、生存的代碼
除了生存前面說的兩個xml文件,DataBinding還生存了相關(guān)的輔助類方便我們在Activity中使用,如下圖所示:

?????DataBinding生成的類
ActivityMainBinding、ActivityMainBindingImpl:這兩個類的名字是根據(jù)布局文件的名字產(chǎn)生的,我們使用的布局文件名字為:activity_main,它這里就是把下劃線去掉,然后按照駝峰式命名法再加上后綴Binding或者BindingImpl生成而來的。相關(guān)的類繼承關(guān)系如下:

這里的BaseObservable是觀察者模式的基類,ViewBinding就是一個接口(畫圖工具沒找到虛線的前頭),ViewDataBinding是Databinding的核心類,也是們的重點分析對象,而這里的ActivityMainBinding、ActivityMainBindingImpl就是根據(jù)我布局文件生成的兩個輔助類,主要是用于輔助數(shù)據(jù)綁定相關(guān)的工作。

這里的有兩個文件名一樣的類DataBinderMapperImpl,但其實他們的功能是不一樣的。左邊的DataBinderMapperImpl類(位于包androidx.databinding下面,可以認為是android提供給的,只不過是由apt在項目編譯期間生存而來)會調(diào)用右邊的DataBinderMapperImpl(位于我們自己的包下面)為他工作,你可以認為全部的工作都是在右邊的DataBinderMapperImpl完成的,左邊那個主要起了一個中間轉(zhuǎn)發(fā)的作用。
到這里關(guān)于DataBinding生存的類關(guān)系說明就完成了,下一章DataBinding原理----布局的加載將說明DataBinding是如何加載布局的。
到此這篇關(guān)于Android DataBinding類關(guān)系深入探究的文章就介紹到這了,更多相關(guān)Android DataBinding 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android?DataBinding布局的加載深入探究
- Android Jetpack組件DataBinding詳解
- Android Jetpack組件支持庫DataBinding與ViewModel與LiveData及Room詳解
- Android淺析viewBinding和DataBinding
- Android開發(fā)使用Databinding實現(xiàn)關(guān)注功能mvvp
- Android?JetPack組件的支持庫Databinding詳解
- Android基礎(chǔ)入門之dataBinding的簡單使用教程
- Android DataBinding單向數(shù)據(jù)綁定深入探究
相關(guān)文章
Android仿微信和QQ多圖合并框架(類似群頭像)的實現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Android仿微信和QQ多圖合并框架的相關(guān)資料,其實就是我們平時所見的群聊頭像,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2017-12-12
關(guān)于Android bitmap你不知道的一些事
這篇文章主要為大家詳細介紹了關(guān)于Android bitmap你不知道的一些事,使用bitmap需要注意的一些細節(jié),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
android 監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化及實戰(zhàn)的示例代碼
本篇文章主要介紹了android 監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化及實戰(zhàn)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
InputFilter實現(xiàn)EditText文本輸入過濾器實例代碼解析
EditText是Android的文本輸入框控件。這篇文章給大家介紹 InputFilter實現(xiàn)EditText文本輸入過濾器實例代碼解析,需要的朋友一起看看吧2016-11-11

