Android?DataBinding類關(guān)系深入探究
一、在相應(yīng)的板塊中開啟DataBinding
dataBinding {
enabled true
}
二、DataBing的簡單使用
這里寫一個(gè)簡單的布局,如下:
<?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>
沒錯(cuò),就是一個(gè)包含兩個(gè)TextView的布局,雖然簡單,但是也能說明DataBinding的原理;但是按照DataBinding對(duì)布局的要求,這并不符合它的要求,所以需要改成如下:
<?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>
仔細(xì)觀察下變動(dòng),兩個(gè)方面:
1、最外層多了一個(gè)layout
2、TextView的賦值使用表達(dá)式@{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 } }
相應(yīng)的ViewModel類如下:
class SimpleViewModel: ViewModel() { private val _first = MutableLiveData("Alice") private val _second = MutableLiveData("Bob") val first: LiveData<String> = _first val second: LiveData<String> = _second }
運(yùn)行應(yīng)用出來的結(jié)果正在預(yù)料之中,這里就不貼圖國;可能你會(huì)好奇,DataBinding是如何把數(shù)據(jù)和布局自動(dòng)綁定的呢?下面就來解密下是怎么回事。
三、生成的xml布局
在Activity中使用的布局名稱是activity_main,生存的輔助類的名字為ActivityMainBinding,這里的ActivityMainBinding是我們直接能夠使用到的類,其實(shí)除了這個(gè)輔助類,還生存了另外兩個(gè)輔助xml文件,只是我們?cè)诖a中使用不到而已。
生存的第一個(gè)布局文件內(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標(biāo)簽),只是做了點(diǎn)變動(dòng);多了一個(gè)tag屬性,這里看不出這個(gè)屬性是干什么用的,但后面我們會(huì)知道他的作用。
生存的第二個(gè)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>
這個(gè)文件就是基于前面的布局文件解析生存而來,里面的元素分別對(duì)應(yīng)到我們布局文件里面的兩個(gè)TextView,這里拿最后一個(gè)元素說下,如下:
<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í)行的表達(dá)式,里面還有個(gè)屬性TwoWay,代表是不是雙向綁定,當(dāng)然這里不是雙向綁定,所以為false。
四、生存的代碼
除了生存前面說的兩個(gè)xml文件,DataBinding還生存了相關(guān)的輔助類方便我們?cè)贏ctivity中使用,如下圖所示:
?????DataBinding生成的類
ActivityMainBinding、ActivityMainBindingImpl:這兩個(gè)類的名字是根據(jù)布局文件的名字產(chǎn)生的,我們使用的布局文件名字為:activity_main,它這里就是把下劃線去掉,然后按照駝峰式命名法再加上后綴Binding或者BindingImpl生成而來的。相關(guān)的類繼承關(guān)系如下:
這里的BaseObservable是觀察者模式的基類,ViewBinding就是一個(gè)接口(畫圖工具沒找到虛線的前頭),ViewDataBinding是Databinding的核心類,也是們的重點(diǎn)分析對(duì)象,而這里的ActivityMainBinding、ActivityMainBindingImpl就是根據(jù)我布局文件生成的兩個(gè)輔助類,主要是用于輔助數(shù)據(jù)綁定相關(guān)的工作。
這里的有兩個(gè)文件名一樣的類DataBinderMapperImpl,但其實(shí)他們的功能是不一樣的。左邊的DataBinderMapperImpl類(位于包androidx.databinding下面,可以認(rèn)為是android提供給的,只不過是由apt在項(xiàng)目編譯期間生存而來)會(huì)調(diào)用右邊的DataBinderMapperImpl(位于我們自己的包下面)為他工作,你可以認(rèn)為全部的工作都是在右邊的DataBinderMapperImpl完成的,左邊那個(gè)主要起了一個(gè)中間轉(zhuǎn)發(fā)的作用。
到這里關(guān)于DataBinding生存的類關(guān)系說明就完成了,下一章DataBinding原理----布局的加載將說明DataBinding是如何加載布局的。
到此這篇關(guān)于Android DataBinding類關(guān)系深入探究的文章就介紹到這了,更多相關(guān)Android DataBinding 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android?DataBinding布局的加載深入探究
- Android Jetpack組件DataBinding詳解
- Android Jetpack組件支持庫DataBinding與ViewModel與LiveData及Room詳解
- Android淺析viewBinding和DataBinding
- Android開發(fā)使用Databinding實(shí)現(xiàn)關(guān)注功能mvvp
- Android?JetPack組件的支持庫Databinding詳解
- Android基礎(chǔ)入門之dataBinding的簡單使用教程
- Android DataBinding單向數(shù)據(jù)綁定深入探究
相關(guān)文章
Android仿微信和QQ多圖合并框架(類似群頭像)的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Android仿微信和QQ多圖合并框架的相關(guān)資料,其實(shí)就是我們平時(shí)所見的群聊頭像,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12關(guān)于Android bitmap你不知道的一些事
這篇文章主要為大家詳細(xì)介紹了關(guān)于Android bitmap你不知道的一些事,使用bitmap需要注意的一些細(xì)節(jié),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11android 監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化及實(shí)戰(zhàn)的示例代碼
本篇文章主要介紹了android 監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化及實(shí)戰(zhàn)的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01Android自定義Style實(shí)現(xiàn)方法
Android自定義Style實(shí)現(xiàn)方法,需要的朋友可以參考一下2013-06-06Libgdx解決部分Android機(jī)型鎖屏崩潰的方法
今天小編就為大家分享一篇關(guān)于Libgdx解決部分Android機(jī)型鎖屏崩潰的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10InputFilter實(shí)現(xiàn)EditText文本輸入過濾器實(shí)例代碼解析
EditText是Android的文本輸入框控件。這篇文章給大家介紹 InputFilter實(shí)現(xiàn)EditText文本輸入過濾器實(shí)例代碼解析,需要的朋友一起看看吧2016-11-11android二級(jí)listview列表實(shí)現(xiàn)代碼
今天來實(shí)現(xiàn)以下大眾點(diǎn)評(píng)客戶端的橫向listview二級(jí)列表,感興趣的朋友可以研究下2013-01-01