此answer向我们展示了如何使用存储库中的liveData
将LiveData
返回到ViewModel
的{{1}}。
现在,如果我们要使用View
怎么办?我们如何转换以下代码以使用LiveData-Ktx中的SavedStateHandle
?
ViewModel:
liveData{}
活动:
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)
}
}
使用viewModel.itemLiveData.observe(this, Observer {
lifecycleScope.launch {/*...update ui...*/}
})
会受益吗?
我可以看到使用liveData{... emit()}
的3个优点:
1-恢复viewModel状态
2-当我们使用SavedStateHandle
时,它会为我们调用.value()
3-stateHandle.set()
帮助我们初始化值(例如,对于stateHandle.getLiveData
也是有帮助的)
答案 0 :(得分:1)
实际上,对于savedStateHandle
来说,get/set
方法对我来说是一个错误。唯一真正可靠的是getLiveData
,您可以使用Transformations.switchMap
将其合并到其他LiveData中。
如果使用getLiveData
支持的类型的android.os.Bundle
,则可以通过它获得状态持久性。如果不这样做,那么您只会崩溃。 getLiveData
已经返回了MutableLiveData
,这就是为什么手动处理get/set
并不是一个好主意,您可以从{{ 1}}(如果需要)。
答案 1 :(得分:0)
我认为您可以做这样的事情
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)
}
}
让我知道它是否对您有帮助。 附言 PageId,它可以是当前页面的编号或其他任何页面标识符