带有协程和SavedStateHandle的liveData

时间:2019-09-24 11:23:14

标签: android android-architecture-components android-livedata kotlin-coroutines

answer向我们展示了如何使用存储库中的liveDataLiveData返回到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也是有帮助的)

2 个答案:

答案 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,它可以是当前页面的编号或其他任何页面标识符