🔀【Jetpack】Android DataBinding 數據綁定 範例🔧
Android Databinding 是 Android 平台上提供的一個壓縮開發流程和提升可維護性的資料綁定機制,其主要功能為簡化 Android 對應用程序 UI 的數據繫結和資料流傳遞,例如將功能控件與資料模型中存儲的數據繫結在一起,使應用程序的最終用戶可以用一個相對簡潔的語法將功能控件的數據(屬性)與資料模型繫結在一起,符合低耦合和高可擴展性的原則,降低程序的開發、維護和測試的成本,提高開發的效率。
文章目錄
- DataBinding & Fragment KTX 導入
- DataBinding
- DataBinding StateFlow 配合 ViewModel 更新 UI
- DataBinding 自定義單參數屬性
- DataBinding 自定義多參數屬性
- DataBinding 導入 View 寫判斷
- Developer Documents DataBinding
1.DataBinding & Fragment KTX 導入
build.gradle
android {
buildFeatures {
dataBinding true
}
}
dependencies {
def fragment_version = "1.5.5"
implementation "androidx.fragment:fragment-ktx:$fragment_version"
}
2.DataBinding
activity_main.xml
<?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="name"
type="String" />
<variable
name="age"
type="Integer" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{name + '\n' + age}"
android:textSize="50sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.name = "Wade"
binding.age = 26
}
}
3.DataBinding StateFlow 配合 ViewModel 更新 UI
PersonViewModel.kt
class PersonViewModel : ViewModel() {
private val _name = MutableStateFlow("Fly")
val name = _name.asStateFlow()
private val _age = MutableStateFlow(20)
val age = _age.asStateFlow()
fun changeData() {
viewModelScope.launch {
_name.emit("Wade")
_age.emit(26)
}
}
}
activity_main.xml
<?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.example.jetpackdemo.PersonViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:onClick="@{() -> viewModel.changeData()}"
android:text="@{viewModel.name + '\n' + viewModel.age}"
android:textSize="50sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val viewModel: PersonViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.viewModel = viewModel
binding.lifecycleOwner = this
}
}
4.DataBinding 自定義單參數屬性
build.gradle
plugins {
id 'kotlin-kapt'
}
BindingAdapters
object BindingAdapters {
@JvmStatic
@BindingAdapter("app:hideIfZero")
fun hideIfZero(view: View, name: String) {
view.isVisible = name == "Wade"
}
}
activity_main.xml
<?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.example.jetpackdemo.PersonViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/appCompatTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:onClick="@{() -> viewModel.changeData()}"
android:text="@{viewModel.name + '\n' + viewModel.age}"
android:textSize="50sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi"
android:textSize="60sp"
app:hideIfZero="@{viewModel.name}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appCompatTextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
5.DataBinding 自定義多參數屬性
BindingAdapters
object BindingAdapters {
@JvmStatic
@BindingAdapter(value = ["app:realText", "app:realTextColor"], requireAll = true)
fun setRealText(view: AppCompatTextView, text: String, color: String) {
view.text = text
view.setTextColor(Color.parseColor(color))
}
}
PersonViewModel.kt
class PersonViewModel : ViewModel() {
private val _name = MutableStateFlow("Fly")
private val _age = MutableStateFlow(20)
private val _hello = MutableStateFlow("Hi")
private val _helloColor = MutableStateFlow("#FF0000")
val name = _name.asStateFlow()
val age = _age.asStateFlow()
val hello = _hello.asStateFlow()
val helloColor = _helloColor.asStateFlow()
fun changeData() {
viewModelScope.launch {
_name.emit("Wade")
_age.emit(26)
_hello.emit("Hello")
_helloColor.emit("#FF00FF")
}
}
}
activity_main.xml
<?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.example.jetpackdemo.PersonViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/appCompatTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:onClick="@{() -> viewModel.changeData()}"
android:text="@{viewModel.name + '\n' + viewModel.age}"
android:textSize="50sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi"
android:textSize="60sp"
app:realText="@{viewModel.hello}"
app:realTextColor="@{viewModel.helloColor}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appCompatTextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
6.DataBinding 導入 View 寫判斷
PersonViewModel
class PersonViewModel : ViewModel() {
private val _name = MutableStateFlow("Fly")
private val _age = MutableStateFlow(20)
private val _nameVisible = MutableStateFlow(true)
val name = _name.asStateFlow()
val age = _age.asStateFlow()
val nameVisible = _nameVisible.asStateFlow()
fun changeData() {
viewModelScope.launch {
_name.emit("Wade")
_age.emit(26)
_nameVisible.emit(false)
}
}
}
activity_main.xml
<?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>
<import type="android.view.View" alias="AndroidView"/>
<variable
name="viewModel"
type="com.example.jetpackdemo.PersonViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/appCompatTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:onClick="@{() -> viewModel.changeData()}"
android:text="@{viewModel.name + '\n' + viewModel.age}"
android:textSize="50sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi"
android:textSize="60sp"
android:visibility="@{viewModel.nameVisible ? AndroidView.VISIBLE : AndroidView.GONE }"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appCompatTextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
7.Developer Documents DataBinding
Open in Documents DataBinding