liveData с сопрограммами и SavedStateHandle - PullRequest
0 голосов
/ 24 сентября 2019

Этот ответ показывает нам, как мы можем использовать liveData в хранилище, чтобы возвратить LiveData в ViewModel, который будет наблюдать View.
Теперь, что если мы хотимиспользовать SavedStateHandle?Как мы можем преобразовать следующий код для использования liveData{} из LiveData-Ktx ?

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)
    }
}

Активность:

viewModel.itemLiveData.observe(this, Observer {
    lifecycleScope.launch {/*...update ui...*/}
})

Получим ли мы выгоду от использования liveData{... emit()}?

Я вижу 3 преимущества от использования SavedStateHandle:
1 - Восстановите ваше состояние viewModel
2 - Он вызывает .value() для нас, когда мыиспользование stateHandle.set()
3 - stateHandle.getLiveData помогает нам инициализировать значение (это также полезно, например, для Data Binding)

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

На самом деле, с savedStateHandle методы get/set кажутся мне ошибкой.Единственный, который действительно надежен - это getLiveData, который вы можете объединить в другие LiveData, используя Transformations.switchMap.

Если вы используете getLiveData с типом, который поддерживается android.os.Bundle, тогда вы получитенастойчивость из коробки через это.Если вы этого не сделаете, то вы просто получите сбои.getLiveData уже возвращает MutableLiveData, поэтому не рекомендуется обрабатывать get/set вручную, вы можете vall .value = на MutableLiveData с SavedStateHandle, если это необходимо.

0 голосов
/ 24 сентября 2019

Я думаю, вы можете сделать что-то вроде этого

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)
    }
}

Дайте мне знать, помогло ли это вам.PS PageId Это может быть номер текущей страницы или любой другой идентификатор страницы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...