【问题标题】:Android LiveData Transformation: Changing LiveData object valueAndroid LiveData 转换:更改 LiveData 对象值
【发布时间】:2020-04-30 22:36:39
【问题描述】:

我有一个包含用户列表的 LiveData 对象,我正在尝试将数据传输到另一个 LiveData 对象以在其他地方使用。

我将 MVVM 与 Room 一起使用,因此我从数据库和 ViewModel 中获取 LiveData,我试图将 LiveData 中的 User 对象转换为 Person 对象以显示在 UI 中。

所以我有一个变量是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

视图模型:

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
}

但当我运行它时,它会崩溃或不更新 UI。

谢谢!

【问题讨论】:

    标签: android kotlin android-livedata android-jetpack


    【解决方案1】:

    您的代码的主要问题是它在var liveList: LiveData 中使用了var,而不是使用val

    您应该像这样声明liveList 变量:

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

    为什么?

    通常,LiveData 变量应始终使用val 声明。原因是LiveData 的目的是让我们观察LiveData 持有的最新值。我们通过这样的代码来做:

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

    使用此代码,我们确保始终显示更新的列表。每当liveList 持有的list 值发生变化时,UI 都会随之更新。但是如果liveList本身也发生了变化,代码只会观察到liveList变量的第一个LiveData,UI不会正确更新。

    【讨论】:

      【解决方案2】:
      val liveList = MutableLiveData(repo.getAll().value.orEmpty().map { user ->
              Person(user.firstName, user.age)
      })
      

      这将是一种更紧凑的方式,如果您愿意,您可以将 repo.getAll() 调用提取到它自己的变量中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 2018-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多