文章目錄
簡介
DataBinding 是 Jitpack 組件之一,適用於 MVVM 模式開發,也是Google官方推薦使用的組件之一。使用DataBinding可以很容易的達到視圖與邏輯分離,直接在佈局中綁定數據,並且數據改變時自動更新UI,不再需要在業務代碼中綁定數據。
本文結合Google官方提供的DataBinding使用示例講解,Google官方sample地址:https://github.com/googlesamples/android-databinding,其中包含兩個工程,本文使用的BasicSample工程。
使用方式
1. build.gradle 中添加 kapt,並啓用dataBinding
在app模塊的build.gradle
文件中,添加:
apply plugin: 'kotlin-kapt'
android {
...
dataBinding {
enabled true
}
}
其中,apply plugin: 'kotlin-kapt'
是爲了在Kotlin中使用BindingAdapter註解。
2.修改佈局文件,添加 layout 和 data 標籤
使用DataBinding的佈局文件與普通的佈局文件有些不同,在佈局外需要包裹一層<layout>
,並添加<data>
標籤,如下所示:
<?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/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
<data>
標籤是用來添加數據的,初次使用,先保持爲空即可。<data>
標籤之後就是正常的佈局代碼,與普通的佈局代碼一模一樣。
接下來,我們在activity_main佈局中添加兩個按鈕:
<?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/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/observable_fields_activity_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Observable Fields activity"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/viewmodel_activity_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="ViewModel activity"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/observable_fields_activity_button"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
寫好佈局文件後rebuild project
,這時generatedJava文件夾下會自動生成databinding需要用到的文件。
3.使用 DataBindingUtil 綁定佈局
由於使用了DataBinding佈局,所以我們需要用DataBindingUtil綁定佈局,而不是直接使用setContentView。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 因爲使用了dataBinding佈局,所以這裏需要用DataBindingUtil來設置佈局
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
// 返回的binding擁有佈局中所有的View,使用id引用即可
binding.observableFieldsActivityButton.setOnClickListener {
startActivity(Intent(this, ObservableFieldActivity::class.java))
}
binding.viewmodelActivityButton.setOnClickListener {
startActivity(Intent(this, ViewModelActivity::class.java))
}
}
}
返回的Binding類型跟佈局文件名有關,規則是佈局文件名去掉下劃線,改成駝峯命名,再添加Binding後綴。比如本例中使用的佈局文件是activity_main.xml,所以返回的Binding類型就是ActivityMainBinding。
返回的binding中擁有佈局中的所有View,使用id即可引用,這裏我們給兩個按鈕添加了兩個點擊事件,點擊跳轉至另外兩個Activity。這裏我們先新建兩個空的Activity,命名爲ObservableFieldActivity和ViewModelActivity,後面我們會修改這兩個Activity的內容。注意由於使用了DataBinding佈局,所以Kotlin直接用id引用View的特性不可用了。
4.佈局的 data 標籤中添加數據變量,並使用其參數
<layout>
中的<data>
用來定義需要綁定的數據,我們先新建一個數據類ObservableFieldProfile:
data class ObservableFieldProfile(
val name: String,
val lastName: String
)
這是一個表示個人信息的類,name表示名字,lastName表示姓氏。
在ObservableFieldActivity的佈局文件中,使用此類定義一個user變量:
<?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="com.example.studydatabinding.data.ObservableFieldProfile"/>
<variable
name="user"
type="ObservableFieldProfile"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.ObservableFieldActivity">
<TextView
android:id="@+id/name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="Name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{user.name}"
app:layout_constraintStart_toStartOf="@id/name_label"
app:layout_constraintTop_toBottomOf="@id/name_label"/>
<TextView
android:id="@+id/lastname_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Last Name"
app:layout_constraintStart_toStartOf="@id/name"
app:layout_constraintTop_toBottomOf="@id/name"/>
<TextView
android:id="@+id/lastname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{user.lastName}"
app:layout_constraintStart_toStartOf="@id/lastname_label"
app:layout_constraintTop_toBottomOf="@id/lastname_label"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
<data>
中的import標籤用於導入使用的類,type表示類的完整路徑,<variable>
標籤用於定義變量,name表示變量名,type表示變量類型。在此例中,我們定義了一個類型爲ObservableFieldProfile的user變量。
使用此變量的方式也很簡單,在佈局文件中,使用@{user.name}
即可使用user變量的name參數,使用@{user.lastName}
即可使用user變量的lastName參數。可以看到,我們給兩個TextView的android:text
屬性設置了user的這兩個參數。
同樣的,寫好佈局文件後需要rebuild Project。
在ObservableFieldActivity中,使用DataBindingUtil設置佈局,並且給返回的binding變量設置user參數,代碼如下:
class ObservableFieldActivity : AppCompatActivity() {
private val observableFieldProfile = ObservableFieldProfile("Alpinist", "Wang")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityObservableFieldBinding = DataBindingUtil.setContentView(this, R.layout.activity_observable_field)
binding.user = observableFieldProfile
}
}
使用binding.user給DataBinding佈局中的user變量賦值。
此時,運行程序,顯示如下:
可以看到,我們綁定的user變量已經成功顯示出來了。
不過此時user變量變化時,UI還不能自動刷新。如果需要UI隨着變量自動刷新,需要將String類型換成ObservableField<String>
類型。如果是int型變量,需要替換成ObservableField<Int>
類型,它等同於ObservableInt
類型,我們以ObservableInt
類型爲例,在ObservableFieldProfile類中新增likes變量,:
data class ObservableFieldProfile(
val name: String,
val lastName: String,
val likes: ObservableInt
)
修改佈局文件activity_observable_field.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">
...
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<TextView
android:id="@+id/likes_label"
android:text="Like"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/likes"
app:layout_constraintTop_toBottomOf="@id/likes_label"
app:layout_constraintStart_toStartOf="@id/likes_label"
app:layout_constraintEnd_toEndOf="@id/likes_label"
android:text="@{Integer.toString(user.likes)}"
android:layout_marginTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/like_button"
app:layout_constraintTop_toBottomOf="@id/likes"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="Like"
android:onClick="onLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
我們在佈局中添加了一個按鈕,點擊一次觸發onLike方法,還添加了一個顯示likes數量的TextView,由於likes是一個Int型變量,所以我們用Integer.toString()方法將其轉換爲了String。
修改ObservableFieldActivity:
class ObservableFieldActivity : AppCompatActivity() {
private val observableFieldProfile = ObservableFieldProfile("Alpinist", "Wang", ObservableInt(0))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityObservableFieldBinding =
DataBindingUtil.setContentView(this, R.layout.activity_observable_field)
binding.user = observableFieldProfile
}
fun onLike(view: View) {
observableFieldProfile.likes.increment()
}
}
fun ObservableInt.increment() {
set(get() + 1)
}
我們在此Activity中添加了onLike()方法,前文已說到,點擊按鈕一次便會觸發一次onLike方法,在此方法中,我們將user的likes變量增加1。其中拓展的increment函數主要是爲了方便調用。
此時,運行程序,效果如下:
爲了讓效果更加酷炫一點,順便複習一下上面學到的內容,我們在佈局中添加一個ImageView和一個ProgressBar:
<?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="com.example.studydatabinding.data.ObservableFieldProfile"/>
<import type="android.view.View"/>
<variable
name="user"
type="ObservableFieldProfile"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.ObservableFieldActivity">
<TextView
android:id="@+id/name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="Name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{user.name}"
app:layout_constraintStart_toStartOf="@id/name_label"
app:layout_constraintTop_toBottomOf="@id/name_label"/>
<TextView
android:id="@+id/lastname_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Last Name"
app:layout_constraintStart_toStartOf="@id/name"
app:layout_constraintTop_toBottomOf="@id/name"/>
<TextView
android:id="@+id/lastname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{user.lastName}"
app:layout_constraintStart_toStartOf="@id/lastname_label"
app:layout_constraintTop_toBottomOf="@id/lastname_label"/>
<ImageView
android:minHeight="48dp"
android:minWidth="48dp"
android:id="@+id/imageView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="24dp"
android:layout_marginTop="24dp"
android:tint="@{user.likes > 9 ? @android:color/holo_red_light : @android:color/black}"
android:src="@{user.likes < 4 ? @drawable/ic_person_black_96dp : @drawable/ic_whatshot_black_96dp}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="Like"
app:layout_constraintEnd_toEndOf="@id/imageView"
app:layout_constraintTop_toBottomOf="@id/imageView"
app:layout_constraintStart_toStartOf="@id/imageView"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:id="@+id/likes_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/likes"
app:layout_constraintTop_toBottomOf="@id/likes_label"
app:layout_constraintStart_toStartOf="@id/likes_label"
app:layout_constraintEnd_toEndOf="@id/likes_label"
android:text="@{Integer.toString(user.likes)}"
android:layout_marginTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/like_button"
app:layout_constraintTop_toBottomOf="@id/likes"
app:layout_constraintEnd_toEndOf="@id/likes"
app:layout_constraintStart_toStartOf="@id/likes"
android:layout_marginTop="8dp"
android:text="Like"
android:onClick="onLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ProgressBar
android:layout_width="0dp"
app:layout_constraintStart_toStartOf="@id/like_button"
app:layout_constraintEnd_toEndOf="@id/like_button"
app:layout_constraintTop_toBottomOf="@id/like_button"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:visibility="@{user.likes > 0 ? View.VISIBLE : View.GONE}"
android:layout_marginTop="8dp"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
其中的兩張Vector圖片代碼如下:
ic_person_black_96dp.xml:
<vector android:height="96dp" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="96dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>
ic_whatshot_black_96dp.xml:
<vector android:height="96dp" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="96dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>
主要添加的邏輯有:
- 如果user.likes大於9,ImageView顯示紅色,否則顯示黑色。
- 如果user.likes小於4,ImageView顯示ic_person_black_96dp圖片,否則顯示ic_whatshot_black_96dp圖片。注意不能直接使用
>
、<
符號,需要用轉義字符>
、<
代替。 - 如果user.likes大於0,顯示ProgressBar,否則隱藏ProgressBar
此時,運行代碼,效果如下:
5.BindingAdapter的使用
BindingAdapter是用來拓展屬性的,新建一個BindingAdapters類,添加以下代碼:
object BindingAdapters {
@BindingAdapter("hideIfZero")
@JvmStatic
fun hideIfZero(view: View, number: Int) {
view.visibility = if (number == 0) View.GONE else View.VISIBLE
}
}
寫好後,rebuild project
,然後就可以在佈局文件中,對View使用hideIfZero
屬性了。BindingAdapter中的參數表示屬性名字,函數中的第一個參數表示View類型,後面的參數表示屬性的值。
BindingAdapter中的屬性名字可以添加命名空間前綴,例如可以寫作app:hideIfZero
,不過這樣的話在xml中就只能使用app:
前綴了。如果像上例中一樣,在BindingAdapter中不添加命名空間前綴,那麼在xml中可以直接使用hideIfZero
或者其他任何除android:
外的前綴,比如app:hideIfZero
,whatever:hideIfZero
等等。
在BindingAdapter中再添加幾個擴展屬性:
object BindingAdapters {
@BindingAdapter("popularityIcon")
@JvmStatic
fun popularityIcon(view: ImageView, popularity: Popularity) {
val color = getAssociateColor(popularity, view.context)
ImageViewCompat.setImageTintList(view, ColorStateList.valueOf(color))
view.setImageDrawable(getDrawablePopularity(popularity, view.context))
}
@BindingAdapter("progressTint")
@JvmStatic
fun tintPopularity(view: ProgressBar, popularity: Popularity) {
val color = getAssociateColor(popularity, view.context)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
view.progressTintList = ColorStateList.valueOf(color)
}
}
@BindingAdapter("progressScaled", "android:max")
@JvmStatic
fun setProgress(progressBar: ProgressBar, likes: Int, max: Int) {
progressBar.progress = (likes * max / 5).coerceAtMost(max)
}
@BindingAdapter("hideIfZero")
@JvmStatic
fun hideIfZero(view: View, number: Int) {
view.visibility = if (number == 0) View.GONE else View.VISIBLE
}
private fun getAssociateColor(popularity: Popularity, context: Context): Int {
return when (popularity) {
Popularity.POPULAR -> ContextCompat.getColor(context, R.color.popular)
Popularity.STAR -> ContextCompat.getColor(context, R.color.star)
else -> Color.BLACK
}
}
private fun getDrawablePopularity(popularity: Popularity, context: Context): Drawable? {
return ContextCompat.getDrawable(
context, when (popularity) {
Popularity.NORMAL -> R.drawable.ic_person_black_96dp
else -> R.drawable.ic_whatshot_black_96dp
}
)
}
}
從setProgress方法可以看出,如果需要獲取xml中其他的屬性值,在BindingAdapter中添加對應的屬性名,再在函數中添加對應的參數即可。
其中的Popularity類如下:
enum class Popularity {
NORMAL,
POPULAR,
STAR
}
編輯activity_view_model,使用上面定義的自定義屬性:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<import type="com.example.studydatabinding.data.ProfileLiveDataViewModel"/>
<variable
name="viewmodel"
type="ProfileLiveDataViewModel"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.ViewModelActivity">
<TextView
android:id="@+id/name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="@string/name_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{viewmodel.name}"
app:layout_constraintStart_toStartOf="@id/name_label"
app:layout_constraintTop_toBottomOf="@id/name_label"/>
<TextView
android:id="@+id/lastname_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/last_name_label"
app:layout_constraintStart_toStartOf="@id/name"
app:layout_constraintTop_toBottomOf="@id/name"/>
<TextView
android:id="@+id/lastname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{viewmodel.lastName}"
app:layout_constraintStart_toStartOf="@id/lastname_label"
app:layout_constraintTop_toBottomOf="@id/lastname_label"/>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:contentDescription="@string/profile_avatar_cd"
android:minWidth="48dp"
android:minHeight="48dp"
app:popularityIcon="@{viewmodel.popularity}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/likes_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/likes"
app:layout_constraintEnd_toEndOf="@id/imageView"
app:layout_constraintStart_toStartOf="@id/imageView"
app:layout_constraintTop_toBottomOf="@id/imageView"/>
<TextView
android:id="@+id/likes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Integer.toString(viewmodel.likes)}"
app:layout_constraintEnd_toEndOf="@id/likes_label"
app:layout_constraintStart_toStartOf="@id/likes_label"
app:layout_constraintTop_toBottomOf="@id/likes_label"/>
<Button
android:id="@+id/like_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:onClick="@{() -> viewmodel.onLike()}"
android:text="@string/like"
app:layout_constraintEnd_toEndOf="@id/likes"
app:layout_constraintStart_toStartOf="@id/likes"
app:layout_constraintTop_toBottomOf="@id/likes"/>
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
app:progressTint="@{viewmodel.popularity}"
app:progressScaled="@{viewmodel.likes}"
android:max="@{100}"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:hideIfZero="@{viewmodel.likes}"
app:layout_constraintEnd_toEndOf="@id/like_button"
app:layout_constraintStart_toStartOf="@id/like_button"
app:layout_constraintTop_toBottomOf="@id/like_button"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
其中的ProfileLiveDataViewModel類如下:
class ProfileLiveDataViewModel : ViewModel() {
private val _name = MutableLiveData("Alpinist")
private val _lastName = MutableLiveData("Wang")
private val _likes = MutableLiveData(0)
val name: LiveData<String> = _name
val lastName: LiveData<String> = _lastName
val likes: LiveData<Int> = _likes
val popularity: LiveData<Popularity> = Transformations.map(_likes) {
when {
it > 9 -> Popularity.STAR
it > 4 -> Popularity.POPULAR
else -> Popularity.NORMAL
}
}
fun onLike(){
_likes.value = _likes.value?.inc()
}
}
LiveData也是jitpack組件之一,其原理和ObservableField是類似的,都是屬於可觀測的屬性。
編輯ViewModelActivity:
class ViewModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel = ViewModelProviders.of(this).get(ProfileLiveDataViewModel::class.java)
val binding: ActivityViewModelBinding = DataBindingUtil.setContentView(this, R.layout.activity_view_model)
binding.viewmodel = viewModel
binding.lifecycleOwner = this
}
}
此時,運行程序,顯示如下: