[英]liveData with Coroutines and SavedStateHandle
This answer show us how can we use liveData
in the repository to return a LiveData
to ViewModel
which the View
will observe.这个答案向我们展示了如何使用存储库中的liveData
将LiveData
返回给View
将观察到的ViewModel
。
Now, what if we want to use SavedStateHandle
?现在,如果我们想使用SavedStateHandle
怎么办? How can we transform the following code to use liveData{}
from LiveData-Ktx ?我们如何转换以下代码以使用LiveData-Ktx中的liveData{}
?
ViewModel:视图模型:
private val _itemLiveData = stateHandle.getLiveData<MyItem>(KEY, MyItem())
val itemLiveData: LiveData<MyItem> = _itemLiveData
suspend fun nextPage() {
viewModelScope.launch {
val item = repoCall...
stateHandle.set(KEY, item)
}
}
Activity:活动:
viewModel.itemLiveData.observe(this, Observer {
lifecycleScope.launch {/*...update ui...*/}
})
Will we benefit from using liveData{... emit()}
?我们会从使用liveData{... emit()}
中受益吗?
I can see 3 advantages of using SavedStateHandle
:我可以看到使用SavedStateHandle
的 3 个优点:
1 - Restore your viewModel state 1 - 恢复您的 viewModel state
2 - It calls .value()
for us when we use stateHandle.set()
2 - 当我们使用stateHandle.set()
时,它会为我们调用.value()
)
3 - stateHandle.getLiveData
helps us initialize the value (this is also helpful with Data Binding
for example) 3 - stateHandle.getLiveData
帮助我们初始化值(这对Data Binding
也很有帮助)
Actually, with savedStateHandle
, the get/set
methods feel like a mistake to me.实际上,使用savedStateHandle
时, get/set
方法对我来说是个错误。 The only one that is truly reliable is getLiveData
, which you can combine into other LiveData using Transformations.switchMap
.唯一真正可靠的是getLiveData
,您可以使用Transformations.switchMap
将其组合到其他 LiveData 中。
If you use getLiveData
with a type that is supported by android.os.Bundle
, then you get state persistence out of the box through it.如果您将getLiveData
与android.os.Bundle
支持的类型一起使用,那么您将通过它获得开箱即用的 state 持久性。 If you don't, then you'll just get crashes.如果你不这样做,那么你只会崩溃。 getLiveData
already returns a MutableLiveData
, which is why it is not a good idea to handle get/set
manually, you can vall .value =
on the MutableLiveData
from SavedStateHandle
if need be. getLiveData
已经返回一个MutableLiveData
,这就是为什么手动处理get/set
不是一个好主意的原因,如果需要,您可以在MutableLiveData
的SavedStateHandle
上使用.value =
。
I think you can do something like this我认为你可以做这样的事情
class SomeViewModel(
private val savedStateHandle: SavedStateHandle
repository:ItemsRepository) : ViewModel() {
companion object {
private const val PAGE_KEY = "page_key"
}
private val _page = MutableLiveData<PageId>(savedStateHandle.get(PAGE_KEY))
private val _itemLiveData = Transformations.switchMap(_page) { pageId -> repository.getNextPage(pageId) }
val itemLiveData: LiveData<MyItem> = _itemLiveData
suspend fun nextPage(pageId: PageId) {
_page.postValue(pageId)
}
override fun onCleared() {
super.onCleared()
savedStateHandle.set(PAGE_KEY, _page.value)
}
}
class ItemsRespository {
fun getNextPage(pageId:PageId) = liveData() {
....
emit(someData)
}
}
Let me know if it helped you.让我知道它是否对您有帮助。 PS PageId it can be number of current page or other any page identifier PS PageId 它可以是当前页面的编号或其他任何页面标识符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.