Android MVVM - Как заставить LiveData испускать данные, которые он имеет (заставляя вызвать наблюдателя) - PullRequest
0 голосов
/ 28 июня 2018

У меня есть ViewModel, который получает список из сети, и я заполняю RecyclerView данными (MyAvailabilityRepository возвращает MutableLiveData, поэтому я использую Transformations.switchMap):

class MyAvailabilityViewModel : ViewModel() {
    private val getListsParams = MutableLiveData<String>()
    private val getListsObservable = Transformations.switchMap(getListsParams) { 
        organizationId -> MyAvailabilityRepository.getSectionedLists(organizationId) 
    }

    fun getListsObservable() : LiveData<Resource<MutableList<SectionedAvailabilityList>>> {
        return getListsObservable
    }

    fun fetchLists(organizationId: String, forceRefresh: Boolean = false) {
        if (getListsParams.value == null || forceRefresh) {
            getListsParams.value = organizationId
        }
    }
}

Фрагмент onActivityCreated:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    ...
    viewModel.getListsObservable().observe(this, Observer { // populate RecyclerView })
    viewModel.fetchLists(organizationId)
}

Так как getListParams.value является нулевым в первый раз, он установит getListsParams.value = organizationId и вызовет switchMap и вызовет хранилище, чтобы получить список из сети.

Когда я хочу принудительно обновить (с помощью pull-to-refresh) и снова вызвать сеть, я могу использовать forceRefresh = true:

override fun onRefresh() {
    viewModel.fetchLists(organizationId, forceRefresh = true)
}

Он установит значение organizationId и вызовет преобразования, которые затем вызовут сеть.

Но у меня есть сценарий, в котором я очищаю данные от адаптера моего RecyclerView. Если после этого пользователь нажимает кнопку, я хотел бы снова вызвать наблюдателя, чтобы я заново заполнил адаптер данными, которые getListsObservable уже получил. Я не хочу вызывать forceRefresh для этого, потому что я уверен, что у меня уже есть данные, и я просто хотел бы снова вызвать наблюдателя, чтобы мой пользовательский интерфейс был обновлен с существующими данными. Так как getListParams.value не является нулевым в этой точке, то ничего не произойдет, когда я позвоню fetchLists(organizationId) позже.

Есть идеи о том, как я могу добиться этого с моей текущей настройкой?

Ответы [ 2 ]

0 голосов
/ 05 апреля 2019

Да, ответ Хун Дуана идеален. Я просто собираюсь расширить этот ответ здесь,

Лучше всего иметь функцию расширения.

Моя функция расширения выглядит следующим образом,

fun <T> MutableLiveData<T>.forceRefresh() {
    this.value = this.value
}

Функция вызывающего абонента выглядит следующим образом,

mutableLiveDataObject.forceRefresh()

Счастливое кодирование !!

0 голосов
/ 28 июня 2018

Попробуйте removeObservers() и observe() еще раз:

viewModel.getListsObservable().removeObservers(this)
viewModel.getListsObservable().observe(this, Observer { // populate RecyclerView })

потому что:

Если в LiveData уже есть набор данных, он будет доставлен наблюдателю.

См. документы .

Или, может быть, вы можете изменить getListsObservable() для возврата MutableLiveData, а затем вызвать setValue вручную:

fun loadCurrentData() {
    getListsObservable.value = getListsObservable.value
}
...