Edit: I rewrote this answer in april 2020 to comply with the latest best practices.
To implement a manual refresh without modifying your existing LiveData
logic, I suggest that your ViewModel
uses an internal MutableLiveData
as trigger, then exposes a single LiveData
backed by a switchMap()
(using that trigger as source) to the Activity or Fragment or Binding class (if you use data binding). When refresh is requested, the ViewModel sends a new value to the source of the switchMap()
, which triggers the creation of a new LiveData
instance that will be used for backing the exposed LiveData and replace the previous one.
This way you don’t have to resubscribe to the LifecycleOwner
during refresh, you only subscribe to the single public LiveData
created by the switchMap()
.
Here is an example:
class Page1ViewModel : ViewModel() {
private val loadTrigger = MutableLiveData(Unit)
fun refresh() {
loadTrigger.value = Unit
}
val textResult: LiveData<String> = loadTrigger.switchMap {
loadData()
}
private fun loadData(): LiveData<String> {
// Load data here and return it in a new LiveData instance
}
}