观察数据 class 的 属性 变化的可变实时数据

Observe mutable live data of a data class's property changes

Android Kotlin Fundamentals中,代码提到使用backing 属性将MutableLiveData封装在ViewModel中,这样只有ViewModel本身可以改变说可变值。与惯例不同,我使用的是数据class。我想观察数据class的属性的变化,并显示在UI.

这是我目前所拥有的。

class CourseViewModel : ViewModel() {
    private var _lastAccessedCourse: MutableLiveData<Course>
    val lastAccessedCourse: LiveData<Course>
        get() = _lastAccessedCourse
    // Some other code...

    fun updateProgress() {
        if (_lastAccessedCourse.value != null)
            _lastAccessedCourse.value = _lastAccessedCourse.value!!.let {
                it.progress += 5
                it
            }
    }

然后,我将观察 UI 中的 lastAccessedCourse,如下所示。单击按钮会更新变量 progress,我观察到的就是这种变化。

binding.fragHomeLaReadButton.setOnClickListener {
    courseViewModel.updateProgress()
}

courseViewModel.lastAccessedCourse.observe(viewLifecycleOwner, Observer {
    binding.fragHomeLaProgress.progress = it.progress
})

我的数据class很简单。

data class Course(
    var name: String,
    var category: String,
    var progress: Int
)

这行得通。但是,我有一个顾虑。当我尝试 updateProgress() 而不设置 _lastAccessedCourse 变量(而只是添加 5 以取得进展时),似乎没有观察到变化。我怀疑这是因为它没有观察到数据 class 的 属性 变化。这是正确的吗?

可以看出,每次调用 updateProgress() 时,我都会向 _lastAccessedCourse 返回一个新的 Course 变量。这有性能缺陷吗?有没有更好的做法来实现我想要的?

A MutableLiveData 仅在 value 更改时通知其观察者。未观察到 class(在您的情况下为 Course)的更改。

为获得最佳实践,请考虑为 Course 使用不可变数据 class 并每次为 LiveData 分配一个新数据:

data class Course(
    val name: String,
    val category: String,
    val progress: Int
)

val course = /* TODO: get current course */
val newCourse = course.copy(progress = course.progress + 5)
_lastAccessedCourse.value = newCourse