为什么我可以在 Android Studio 中将 String 或 LiveData<string> 变量绑定到 android:text?

Why can I bind either String or LiveData<string> varaiable to android:text in Android Studio?

我正在学习数据绑定,以下代码来自project.

plain_activity_solution_3.xml中的android:textname绑定到SimpleViewModel,即String.

solution.xml中的android:text绑定到SimpleViewModelSolutionname,即LiveData<String>

为什么 StringLiveData<string> 可以绑定到 android:text?在我看来,只允许绑定一个 android:text.

SimpleViewModel.kt

class SimpleViewModel : ViewModel() {
    val name = "Grace"
    val lastName = "Hopper"
    var likes = 0
        private set // This is to prevent external modification of the variable.
    ...
}

plain_activity_solution_3.xml

<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.android.databinding.basicsample.data.SimpleViewModel"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/plain_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="128dp"
            android:text="@{viewmodel.name}"
    ...
}

SimpleViewModelSolution.kt

class SimpleViewModelSolution : ViewModel() {
    private val _name = MutableLiveData("Ada")
    private val _lastName = MutableLiveData("Lovelace")
    private val _likes =  MutableLiveData(0)

    val name: LiveData<String> = _name
    val lastName: LiveData<String> = _lastName
    val likes: LiveData<Int> = _likes
    ...
}

solution.xml

<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.android.databinding.basicsample.data.SimpleViewModelSolution"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- A simple binding between a TextView and a string observable in the ViewModel -->
        <TextView
            android:id="@+id/name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="128dp"
            android:text="@{viewmodel.name}"
...
}

正如 document 所说:

Any plain-old object can be used for data binding, but modifying the object doesn't automatically cause the UI to update. Data binding can be used to give your data objects the ability to notify other objects, known as listeners, when its data changes.

LiveData<string> 也是可见的。

这是设计使然,并在 documentation 中进行了讨论。活页夹将接受本机数据类型或“可观察的”类型,如 LiveData。如果提供了一个可观察对象,活页夹将订阅该对象的更改并将它们绑定到视图,从而节省您的代码行数。