Jetpck 才是真的豪華全家桶
引言
- DataBinding 實現(xiàn)了視圖與數(shù)據(jù)的雙向綁定,代碼簡潔,Activity 中代碼不再因此膨脹。
- DataBinding 帶來了軟件架構(gòu)的新模式 MVVM 。
- 如果使用 DataBinding 的主要目的是取代 findViewById() 調(diào)用,請考慮改用 ViewDataBinding。
- 靈活強大的框架,會帶來學習成本的提升,深度掌握它,做工具的主人。
整體預(yù)覽

用圖說話
?文章較長,考慮到心急的寶寶們看不到最后,所以總結(jié)性的圖,放到最前面吧!
1. DataBinding 數(shù)據(jù)流向 生成綁定類:

2. DataBinding 數(shù)據(jù)流向 綁定類相互關(guān)系:

3. DataBinding 數(shù)據(jù)流向 普通-數(shù)據(jù)對象:

4. DataBinding 數(shù)據(jù)流向 可觀察-數(shù)據(jù)對象:

5. DataBinding 數(shù)據(jù)流向 雙向數(shù)據(jù)綁定:

6. DataBinding 數(shù)據(jù)流向 橫向?qū)Ρ?/strong>:

1. 語法說明
1.1 環(huán)境配置
? 模塊啟用
//build.gradle
android {
buildFeatures {
dataBinding true
}
}
1.2 布局文件格式
1.2.1 數(shù)據(jù)綁定布局文件
?以根標記 layout 開頭,后跟 data 元素和 view 根元素。綁定視圖的根其實是View根元素。
<?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>
//data 中的 user 變量描述了可在此布局中使用的屬性。
<variable
name="user"
type="com.kejiyuanren.jetpack.databinding.ViewModel" />
</data>
//布局中的表達式使用“@{}”語法寫入特性屬性中。
//在這里,TextView文本被設(shè)置為 user 變量的 userName 屬性
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".databinding.DataBindingActivity">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="@{user.userName}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Tips:布局表達式應(yīng)保持精簡,因為它們無法進行單元測試,并且擁有的 IDE 支持也有限。
1.2.2 數(shù)據(jù)對象
?定義一個最簡單的數(shù)據(jù)對象。
data class ViewModel(val userName:String)
1.3 生成綁定類
?生成的綁定類將布局變量與布局中的視圖關(guān)聯(lián)起來。所有生成的綁定類都是從 ViewDataBinding 類繼承而來的。系統(tǒng)會為每個布局文件生成一個綁定類(綁定類名稱規(guī)則:布局文件名為 activity_main.xml,因此生成的對應(yīng)類為 ActivityMainBinding)。
1.3.1 創(chuàng)建綁定對象
?創(chuàng)建綁定類的方式有很多種。
class DataBindingActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//普通實現(xiàn)
// setContentView(R.layout.activity_data_binding2)
//綁定實現(xiàn) 1
val binding: ActivityDataBinding2Binding = DataBindingUtil.setContentView(
this,
R.layout.activity_data_binding2
)
binding.user = ViewModel("kejiyuanren - 1")
//綁定實現(xiàn)2(其實binding類的生成,主要就是 DataBindingUtil類 和 xxxBinding類 中的實現(xiàn))
// val binding2: ActivityDataBinding2Binding =
// ActivityDataBinding2Binding.inflate(layoutInflater)
// setContentView(binding2.root)
// binding2.user = ViewModel("keyijiyuanren-2")
}
}
Tips:綁定類創(chuàng)建匯總(xxxBinding最終依然會調(diào)到 DataBindingUtil)。

1.3.2 帶 ID 的視圖
?數(shù)據(jù)綁定庫會針對布局中具有 ID 的每個視圖在綁定類中創(chuàng)建不可變字段。相較于針對布局中的每個視圖調(diào)用 findViewById() 方法,這種機制速度更快。如果沒有數(shù)據(jù)綁定,則 ID 并不是必不可少的,但仍有一些情況必須能夠從代碼訪問視圖。
1.3.3 變量
?數(shù)據(jù)綁定庫為布局中聲明的每個變量生成訪問器方法( setter 和 getter )。
//xml code
<layout ……>
<data>
<variable
name="star"
type="int" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<TextView
……
android:text="@{String.valueOf(star)}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//java code
binding.setStar(5)
1.3.4 ViewStub
?ViewStub是可用于延遲加載視圖的組件。在DataBinding中的用法如下:
//xml code -> activity.xml
<layout ……>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<ViewStub
android:layout="@layout/view_stub_tip"
…… />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//xml code -> view_stub_tip.xml
<layout ……>
<data>
<variable
name="tipModel"
type="com.kejiyuanren.jetpack.databinding.TipViewModel" />
</data>
<TextView
android:text="@{tipModel.tipInfo}"
……/>
</layout>
//java code
fun viewStubAdd() {
//視圖擴展監(jiān)聽器, 獲取已經(jīng)生成的綁定類,并執(zhí)行更新操作
binding.viewStubExpand.setOnInflateListener { _, inflated ->
//OK : 方式 1,直接獲取了view的binding緩存(因為binding已經(jīng)生成過了,在ViewStubProxy中)
val vb1: ViewStubTipBinding? = DataBindingUtil.bind(inflated)
//OK : 方式 2,直接獲取 ViewStubProxy中的 binding緩存
// val vb2 = binding.viewStubExpand.binding as ViewStubTipBinding
//ERROR : 方式 3, 直接通過擴展layout的綁定類生成,因為在ViewStubProxy中已經(jīng)創(chuàng)建過了
//創(chuàng)建過的binding類會清空view對應(yīng)的tag, 所以會報錯(view must have a tag)
//這種機制也保證了,binding類的單例特性
// val vb3 = ViewStubTipBinding.bind(inflated)
vb1?.tipModel = TipViewModel("666")
}
//延遲5s觸發(fā)加載擴展視圖
binding.root.postDelayed({
val vs: ViewStub? = binding.viewStubExpand.viewStub
vs?.inflate()
}, 5000)
}
1.3.5 動態(tài)變量
?有時,系統(tǒng)并不知道特定的綁定類。例如,針對任意布局運行的 RecyclerView.Adapter 不知道特定綁定類。在調(diào)用 onBindViewHolder() 方法時,仍必須指定綁定值。比如:RecyclerView 綁定到的所有布局都有 itemModel 變量。
//xml code
<layout ……>
<data>
<variable
name="itemModel"
type="com.kejiyuanren.jetpack.databinding.ItemViewModel" />
</data>
<TextView
android:text="@{itemModel.name}"
…… />
</layout>
//java code
import com.kejiyuanren.jetpack.BR //記得要引入 BR,不然會報錯(Unresolved reference: BR)
class RvAdapter(private val mData: List<ItemViewModel>) :
RecyclerView.Adapter<RvAdapter.RvViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvViewHolder {
val db = ItemDbRvTextBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return RvViewHolder(db)
}
override fun getItemCount(): Int {
return mData.size
}
override fun onBindViewHolder(holder: RvViewHolder, position: Int) {
holder.vb.setVariable(BR.itemModel, mData[position])
//當可變或可觀察對象發(fā)生更改時,綁定會按照計劃在下一幀之前發(fā)生更改。
//但有時必須立即執(zhí)行綁定。要強制執(zhí)行,請使用 executePendingBindings()` 方法。
holder.vb.executePendingBindings()
}
class RvViewHolder(binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
val vb = binding
}
}
1.3.6 自定義綁定類名稱
?默認情況下,綁定類是根據(jù)布局文件的名稱生成的。通過調(diào)整 data 元素的 class 特性,綁定類可重命名或放置在不同的包中。
//xml code
<layout ……>
<data class="KeJiYuanRen">
</data>
</layout>
//java code
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//綁定類已經(jīng)變?yōu)榱俗远x,不再是默認的命名規(guī)則類
val binding: KeJiYuanRen = DataBindingUtil.setContentView(
this,
R.layout.activity_data_binding2
)
}
1.4 綁定適配器
?綁定適配器負責發(fā)出相應(yīng)的框架調(diào)用來設(shè)置值。
1.4.1 自動選擇方法
?您可以使用數(shù)據(jù)綁定為任何 setter 創(chuàng)建特性。以 android:text="@{user.name}" 表達式為例,庫會查找接受 user.getName() 所返回類型的 setText(arg) 方法。如果 user.getName() 的返回類型為 String,則庫會查找接受 String 參數(shù)的 setText() 方法。
1.4.2 指定自定義方法名稱
?一些屬性具有名稱不符的 setter 方法(比如TextView中就沒有setText(arg : Int))。那么就可以自定義方法名稱,使用 BindingMethods注釋與 setter 相關(guān)聯(lián)。注釋與類一起使用,可以包含多個 BindingMethod注釋,每個注釋對應(yīng)一個重命名的方法。
//xml code
<layout ……>
<data>
<variable
name="star"
type="int" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<com.kejiyuanren.jetpack.databinding.Number
app:number="@{star}"
……/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//java code
@BindingMethods( //自定義方法名稱集合,可以包含多個BindingMethod
value = [ //這是個數(shù)組
BindingMethod(
type = TextView::class, //要操作的屬性屬于哪個類
attribute = "number", //xml屬性,使用(app:number=“20”)
method = "setTextNumber" //指定xml屬性對應(yīng)的set方法,參數(shù)類型要對應(yīng)
)]
)
class Number @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TextView(context, attrs, defStyleAttr) {
fun setTextNumber(number : Int) {
text = number.toString()
}
}
1.4.3 提供自定義邏輯
?一些屬性需要自定義綁定邏輯。參數(shù)類型非常重要。第一個參數(shù)用于確定與特性關(guān)聯(lián)的視圖類型,第二個參數(shù)用于確定在給定特性的綁定表達式中接受的類型。
//xml code
<ImageView app:imageUrl="@{venue.imageUrl}" app:error="@{@drawable/venueError}" />
//java code
//如果不需要同時滿足,則requireAll設(shè)置為false
@BindingAdapter(value = ["imageUrl", "placeholder"], requireAll = true)
fun loadImage(view: ImageView, url: String, error: Drawable) {
Picasso.get().load(url).error(error).into(view)
}
1.4.4 自動轉(zhuǎn)換對象
?當綁定表達式返回 Object 時,庫會選擇用于設(shè)置屬性值的方法。如果參數(shù)類型不明確,則必須在表達式中強制轉(zhuǎn)換返回類型。
1.4.5 自定義轉(zhuǎn)換
?在某些情況下,需要在特定類型之間進行自定義轉(zhuǎn)換。轉(zhuǎn)換器是全局的,請謹慎使用。
//xml code
<layout ……>
<data>
<variable
name="show"
type="boolean" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<TextView
android:visibility="@{show}"
……/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//java code
object DbAdapter {
@BindingConversion
@JvmStatic
fun setShowView(show: Boolean): Int {
return if (show) {
View.VISIBLE
} else {
View.GONE
}
}
}
2. 擴展語法
2.1 布局和綁定表達式
2.1.1 表達式語言
?表達式語言與托管代碼中的表達式非常相似。
2.1.1.1 Null 合并運算符
//傳統(tǒng)方式
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
//Null 合并運算符方式
android:text="@{user.displayName ?? user.lastName}"
2.1.1.2 避免出現(xiàn) Null 指針異常
?生成的數(shù)據(jù)綁定代碼會自動檢查有沒有 null 值并避免出現(xiàn) Null 指針異常。例如,在表達式 @{user.name} 中,如果 user 為 Null,則為 user.name 分配默認值 null。如果引用 user.age,其中 age 的類型為 int,則數(shù)據(jù)綁定使用默認值 0。
2.1.1.3 視圖引用
?表達式可以通過語法(綁定類將 ID 轉(zhuǎn)換為駝峰式大小寫),按 ID 引用布局中的其他視圖。
//TextView 視圖引用同一布局中的 EditText 視圖
<EditText
android:id="@+id/example_text"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<TextView
android:id="@+id/example_output"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{exampleText.text}"/>
2.1.1.4 集合
?為方便起見,可使用 [] 運算符訪問常見集合,例如數(shù)組、列表、稀疏列表和映射。
<data>
<import type="java.util.List"/>
<variable name="list" type="List<String>"/>
<variable name="index" type="int"/>
</data>
…
android:text="@{list[index]}"
2.1.1.5 字符串字面量
//可以使用單引號括住特性值,這樣就可以在表達式中使用雙引號
android:text='@{map["firstName"]}'
//也可以使用雙引號括住特性值。如果這樣做,則還應(yīng)使用反單引號 ` 將字符串字面量括起來
android:text="@{map[`firstName`]}"
2.1.1.6 資源
//簡單
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"
//提供參數(shù)來評估格式字符串和復(fù)數(shù)形式
android:text="@{@string/nameFormat(firstName, lastName)}"
2.1.2 事件處理
?通過數(shù)據(jù)綁定,您可以編寫從視圖分派的表達式處理事件(例如,onClick() 方法)。
2.1.2.1 方法引用
//xml code
<layout ……>
<data>
<variable
name="click"
type="com.kejiyuanren.jetpack.databinding.ClickHandler" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<TextView
android:onClick="@{click::onBtnClick}"
……/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//java code
class ClickHandler {
fun onBtnClick(view: View) {
Log.d(TAG, "onBtnClick: ")
}
}
2.1.2.2 監(jiān)聽器綁定
?監(jiān)聽器綁定是在事件發(fā)生時運行的綁定表達式。它們類似于方法引用,但允許運行任意數(shù)據(jù)綁定表達式。
//總有一款適合你
android:onClick="@{() -> presenter.onSaveClick(task)}"
android:onClick="@{(view) -> presenter.onSaveClick(task)}"
android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"
android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"
2.1.3 導(dǎo)入、變量和包含
2.1.3.1 導(dǎo)入
?通過導(dǎo)入功能,您可以輕松地在布局文件中引用類,就像在托管代碼中一樣??梢栽?data 元素使用多個 import 元素,也可以不使用。
<data>
<import type="com.kejiyuanren.jetpack.databinding.View"
alias="UnitView"/> //類型別名,防止與下面的沖突
<import type="android.view.View"/> //引入View
</data>
<TextView
android:text="@{user.lastName}"
android:text="@{((User)(user.connection)).lastName}" //類型強轉(zhuǎn)
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/> //使用View
2.1.3.2 變量
?您可以在 data 元素中使用多個 variable 元素。
2.1.3.3 包含
?通過使用應(yīng)用命名空間和特性中的變量名稱,變量可以從包含的布局傳遞到被包含布局的綁定。注意:數(shù)據(jù)綁定不支持 include 作為 merge 元素的直接子元素。
//activity.xml
<layout ……>
<data>
<variable
name="user"
type="com.kejiyuanren.jetpack.databinding.ViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<TextView
android:text="@{user.userName}"
…… />
<include
layout="@layout/layout_title_append"
app:user="@{user}"
……/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//layout_title_append.xml
<layout ……>
<data>
<variable
name="user"
type="com.kejiyuanren.jetpack.databinding.ViewModel" />
</data>
<TextView
android:text="@{user.userName.toUpperCase()}"
……>
</TextView>
</layout>
2.2 可觀察的數(shù)據(jù)對象
?可觀察性是指一個對象將其數(shù)據(jù)變化告知其他對象的能力。通過數(shù)據(jù)綁定庫,您可以讓對象、字段或集合變?yōu)榭捎^察。
2.2.1 可觀察字段
在創(chuàng)建實現(xiàn) Observable 接口的類時要完成一些操作,但如果您的類只有少數(shù)幾個屬性,這樣操作的意義不大。字段設(shè)為可觀察字段:ObservableXXX。
//數(shù)據(jù)模型
class ViewModel {
val userName = ObservableField<String>()
}
//觀察更新
val userModel = ViewModel()
userModel.userName.set("keyijiyuanren-1")
binding.user = userModel
binding.click = ClickHandler(object : ClickListener{
override fun onClick() {
userModel.userName.set("replace = $count")
}
})
2.2.2 可觀察對象
實現(xiàn) Observable 接口的類允許注冊監(jiān)聽器,以便它們接收有關(guān)可觀察對象的屬性更改的通知。
//數(shù)據(jù)模型
class ViewModel : BaseObservable() {
@get:Bindable
var userName: String = ""
set(value) {
field = value
notifyPropertyChanged(BR.userName)
}
}
//觀察更新
val userModel = ViewModel()
userModel.userName = "keyijiyuanren-1"
binding.user = userModel
binding.click = ClickHandler(object : ClickListener{
override fun onClick() {
userModel.userName = "replace = $count"
}
})
2.3 數(shù)據(jù)雙向綁定
?雙向綁定可以在上面的 2.2.1 可觀察字段基礎(chǔ)上,在xml中使用語法:@={} 表示法(其中重要的是包含“=”符號)可接收屬性的數(shù)據(jù)更改并同時監(jiān)聽用戶更新。
//xml code
<CheckBox
android:checked="@={checkModel.check}"
…… />
//java code
class CheckModel {
val check = ObservableBoolean(false)
}
2.3.1 使用自定義特性的雙向數(shù)據(jù)綁定
&emsp;最常見的雙向特性和更改監(jiān)聽器提供了雙向數(shù)據(jù)綁定實現(xiàn),可以將其用作應(yīng)用的一部分。如果希望結(jié)合使用雙向數(shù)據(jù)綁定和自定義特性,則需要使用 @InverseBindingAdapter 和 @InverseBindingMethod 注釋。
?下面實現(xiàn)了SeekBar的透明度與進度隨動。
//xml code
<layout ……>
<data>
<variable
name="defineAlpha"
type="float " />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<SeekBar
app:okAlpha="@={defineAlpha}"
…… />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//java code
//第三步:獲取到已經(jīng)更新了的defineAlpha數(shù)據(jù),并更新 okAlpha 的 BindingAdapter方法
@BindingAdapter("okAlpha")
@JvmStatic
fun setOkAlpha(okBar: SeekBar, newValue: Float) {
okBar.alpha = newValue
}
//第二步:滑動觸發(fā) okAlpha 的 InverseBindingAdapter方法調(diào)用,獲取屬性okAlpha的值,更新defineAlpha的數(shù)據(jù)
@InverseBindingAdapter(attribute = "okAlpha")
@JvmStatic
fun getOkAlpha(okSeekBar: SeekBar): Float {
return okSeekBar.progress / 100f
}
@BindingAdapter("app:okAlphaAttrChanged")
@JvmStatic
fun setListeners(
okSeekBar: SeekBar,
attrChange: InverseBindingListener
) {
// Set a listener for click, focus, touch, etc.
okSeekBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
//第一步:監(jiān)聽滑動,會觸發(fā) okAlphaAttrChanged 的屬性 okAlpha 的 InverseBindingAdapter方法
attrChange.onChange()
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
}
2.3.2 轉(zhuǎn)換器
?如果綁定到 View對象的變量需要設(shè)置格式、轉(zhuǎn)換或更改后才能顯示,則可以使用 Converter 對象。較簡單。
2.3.3 使用雙向數(shù)據(jù)綁定的無限循環(huán)
?使用雙向數(shù)據(jù)綁定時,請注意不要引入無限循環(huán)。當用戶更改特性時,系統(tǒng)會調(diào)用使用@InverseBindingAdapter 注釋的方法,并且該值將分配給后備屬性。繼而調(diào)用使用 @BindingAdapter 注釋的方法,從而觸發(fā)對使用 @InverseBindingAdapter 注釋的方法的另一個調(diào)用,依此類推。
?因此,通過比較使用 @BindingAdapter 注釋的方法中的新值和舊值,可以打破可能出現(xiàn)的無限循環(huán)。
2.3.4 雙向特性
?平臺對部分控件提供對雙向數(shù)據(jù)綁定的內(nèi)置支持。比如 TextViewBindingAdapter。
2.4 布局綁定架構(gòu)組件
?數(shù)據(jù)綁定庫可與架構(gòu)組件(AndroidX 庫包含的架構(gòu)組件)無縫協(xié)作,進一步簡化界面的開發(fā)。在后面的ViewModel和LiveData中再展開。
3. DataBinding文件說明
3.1 綁定類路徑
3.1.1 JavaModel 視圖層
?參考 Jetpack ViewBinding。
3.1.2 JavaModel 數(shù)據(jù)層
?路徑:app/build/generated/source/kapt/buildTypes

3.1.3 Layout文件
?參考 Jetpack ViewBinding。
3.2 綁定類作用
3.2.1 JavaModel 視圖層
?JavaModel 視圖層(抽象類),繼承自 ViewDataBinding,功能類似ViewBinding。參考 Jetpack ViewBinding。
3.2.2 JavaModel 數(shù)據(jù)層
?JavaModel 數(shù)據(jù)層,繼承自 視圖層,添加的數(shù)據(jù)綁定的功能。
- BR:綁定屬性的字段。
- DataBindingComponent:綁定類作用域。
- DataBinderMapperImpl:
- androidx.databinding 路徑下:全局緩存添加器。
- com.xx.xx(包名)路徑下:全局緩存器。
- XxxBindingImpl:綁定類的字段更新策略,綁定類的生成單例策略等。
3.2.3 Layout文件
?用于生成JavaModel(綁定類)。參考 Jetpack ViewBinding。
4. DataBinding原理分析
4.1 布局綁定類生成
?參考 Jetpack ViewBinding。
4.2 數(shù)據(jù)綁定類生成
?參考 Jetpack ViewBinding。
4.3 綁定功能的數(shù)據(jù)流向
?直接來個最全的吧。雙向綁定數(shù)據(jù)流向:更新數(shù)據(jù)刷新視圖 vs 更新視圖刷新數(shù)據(jù)。
?例子代碼:
//xml code
<layout ……>
<data>
<variable
name="checkModel"
type="com.kejiyuanren.jetpack.databinding.CheckModel " />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
……>
<CheckBox
android:checked="@={checkModel.check}"
…… />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
//java code
class CheckModel {
val check = ObservableBoolean(false)
}
//java 更新操作
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityDataBinding2Binding = DataBindingUtil.setContentView(
this,
R.layout.activity_data_binding2
)
//設(shè)置java模型
var checkModel = CheckModel()
binding.checkModel = checkModel
binding.click = ClickHandler(object : ClickListener{
override fun onClick() {
//輔助button,點擊,執(zhí)行反向選擇設(shè)置
checkModel.check.set(!checkModel.check.get())
}
})
}
?流程圖示:

5.小結(jié)
?DataBinding 催生了 MVVM,代碼簡潔松耦合。JetPack-Compose 才是大Boss,比DB還DB。不過目前還沒有穩(wěn)定版,期待……
?
小編的博客系列
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 系列文章 【背上Jetpack】Jetpack 主要組件的依賴及傳遞關(guān)系【背上Jetpack】AdroidX下使用...
- Jetpack之DataBinding 官方地址 1.簡述 DataBinding是一個用于將數(shù)據(jù)綁定到應(yīng)用界面布...
- 一、前言 DataBinding 數(shù)據(jù)綁定庫屬于谷歌在2018推出Android jetpack(外網(wǎng))其中的軟件...
- Jetpack系列Android Jetpack WorkManager初級認識Android Jetpack V...
- 數(shù)據(jù)綁定庫是一個支持庫,允許您使用聲明性格式而不是以編程方式將布局中的UI組件綁定到應(yīng)用程序中的數(shù)據(jù)源。 布局通常...