Android Преобразование LiveData: изменение значения объекта LiveData - PullRequest
0 голосов
/ 01 мая 2020

У меня есть один объект LiveData, который содержит список пользователей, и я пытаюсь перенести данные в другой объект LiveData для использования в другом месте.

Я использую MVVM с комнатой, поэтому я получаю LiveData из В базе данных и в ViewModel я пытаюсь преобразовать объект User в LiveData в объект Person для отображения в пользовательском интерфейсе.

Итак, у меня есть одна переменная LiveData<List<User>>

class User(var firstName: String, var lastName: String, var age: Integer)

, и я пытаюсь преобразовать его в LiveData<List<Person>> (как пример)

class Person() {

    lateinit var firstName: String

    lateinit var age: Integer
}

, и я пытаюсь изменить их, используя LiveData Transformations.map

ViewModel :

val list2: LiveData<List<User>> = repo.getAll()
var liveList: LiveData<ArrayList<Person>> = MutableLiveData()
liveList = Transformations.map(list2) { list ->
    val newList: ArrayList<Person> = ArrayList()
    list?.forEach {
        val temp = Person()
        temp.firstName = it.firstName
        temp.age = it.age
        newList.add(temp)
    }
    return@map newList
}

но когда я его запускаю, он падает или не обновляет интерфейс.

Спасибо!

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Основная проблема с вашим кодом состоит в том, что он использует var в var liveList: LiveData вместо использования val.

Вы должны объявить переменную liveList следующим образом:

val liveList = Transformations.map(list2) { list ->
   ...
}

Почему?

Как правило, переменная LiveData всегда должна объявляться с val. Причина в том, что цель LiveData состоит в том, чтобы позволить нам наблюдать современное значение, хранящееся в LiveData. Мы делаем это с помощью кода, подобного следующему:

liveList.observe(this) { list ->
    showList(list)
}

С помощью этого кода мы гарантируем, что обновленный список всегда отображается. Всякий раз, когда значение list, которое удерживается liveList, изменяется, в результате пользовательский интерфейс обновляется. Но если сам liveList также изменится, код будет наблюдать только первую LiveData переменной liveList, и пользовательский интерфейс не будет корректно обновлен.

0 голосов
/ 01 мая 2020
val liveList = MutableLiveData(repo.getAll().value.orEmpty().map { user ->
        Person(user.firstName, user.age)
})

Это был бы более компактный способ, вы могли бы вытащить вызов repo.getAll () в его собственную переменную, если вам нравится

...