Reputation: 7433
In Android Kotlin Fundamentals, the code mentions of using a backing property to encapsulate the MutableLiveData
in ViewModel
so that only the ViewModel
itself can change said mutable value. Different from the practice, I'm using a data class instead. I would like to observe the changes to the property of the data class and display it in the UI.
Here's what I have so far.
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
}
}
Then, I will observe the lastAccessedCourse
in my UI like below. A button click updates the variable progress
and that change is what I am observing.
binding.fragHomeLaReadButton.setOnClickListener {
courseViewModel.updateProgress()
}
courseViewModel.lastAccessedCourse.observe(viewLifecycleOwner, Observer {
binding.fragHomeLaProgress.progress = it.progress
})
My data class is simple.
data class Course(
var name: String,
var category: String,
var progress: Int
)
This works. However, I have a concern. When I tried to updateProgress()
without setting _lastAccessedCourse
variable (and instead just adding 5
to progress), it seems like the change isn't observed. I suspect that this is because it doesn't observe the data class's property changes. Is this correct?
As can be seen, I'm returning a new Course
to _lastAccessedCourse
variable every time I call updateProgress()
. Does this have a performance drawback? Is there a better practice to achieve what I want?
Upvotes: 1
Views: 4488
Reputation: 29260
A MutableLiveData
only notifies its observers if the value
is changed. Changes to the class (Course
in your case) are not observed.
For best practice, consider using an immutable data class for Course
and assigning a new one to the LiveData
each time:
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
Upvotes: 3