Логика Android основана на нескольких значениях данных в реальном времени - PullRequest
0 голосов
/ 24 августа 2018

Я использую библиотеку привязки данных Android для создания реактивных представлений с LiveData

Я делаю запрос репо на список вакансий

var jobsRequest: LiveData<Resource<List<Job>>>
    = Transformations.switchMap(position) { repo.getJobsWithStatus(it) }

Тогда у меня есть еще 3 LiveData на основе вышеупомянутого, например,

Сначала проверьте, завершился ли запрос

private val requestComplete: LiveData<Boolean>
    = Transformations.map(jobsRequest) { 
        it.status == Status.SUCCESS || it.status == Status.ERROR 
      }

Далее, чтобы преобразовать в список заданий без оболочки ресурса

var jobs: LiveData<List<Job>>
    = Transformations.map(jobsRequest) { it.data }

Наконец, чтобы проверить, пуст ли этот список заданий

val jobsEmpty: LiveData<Boolean>
    = Transformations.map(jobs) { (it ?: emptyList()).isEmpty() }

В макете я хочу показать счетчик загрузки, если запрос еще не завершен, а список заданий пуст и требуется переменная в моей модели представления, чтобы продиктовать это

Я попробовал приведенный ниже код, и, как и ожидалось, он не работает

val spinnerVisible: LiveData<Boolean>
    = Transformations.map(requestComplete) {
        !(requestComplete.value ?: false) && (jobsEmpty.value ?: true)
      }

Как правильно использовать переменную LiveData на основе состояния двух других - я хочу сохранить всю логику в модели представления, а не в действии или макете.

1 Ответ

0 голосов
/ 25 августа 2018

Нужен ли jobsEmpty наблюдатель? Похоже, вы можете использовать jobs один для него.

Anway, на ваш вопрос: Для этого есть MediatorLiveData. Он делает то, что вам нужно: он может объединять несколько (в вашем случае: 2) объектов LiveData и может определять другое значение жилпата на основе этого.

Какой-то псевдокод:

MediatorLiveData showSpinner = new MediatorLiveData<Boolean>()
showSpinner.addSource(jobsEmpty, { isEmpty ->
    if (isEmpty == true || requestComplete.value == true) {
       // We should show!
       showSpinner.value = true
    }
    // Remove observer again
    showSpinner.removeSource(jobsEmpty);
})
showSpinner.addSource(requestComplete, { isCompleted ->
    if (isCompleted == true && jobsEmpty == true) {
       // We should show!
       showSpinner.value = true
    }
    // Remove observer again
    showSpinner.removeSource(requestComplete);
})
return showSpinner

Обратите внимание, что в качестве результата вы должны вернуть mediatorlivedata, так как это интересующий вас объект для макета.

Кроме того, вы можете проверить документацию на MediatorLiveData, у нее есть еще несколько примеров: https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData

...