将 MutableList 包装在 LiveData 或 MutableLiveData 中

问题描述 投票:0回答:2

MutableList
包装在
LiveData
MutableLiveData
中的建议方法是什么,以便可以修改列表并观察其所发生的变化?

我有一些相当短的表(<20 items) in Room (It caches the values retrieved from a server). I would like to retain a mutable subset of these items; to be used as filters in queries for other, larger, tables. My thinking was to assign a

MutableList
到我的应用程序中的模型类,并通过将此类包装在
MutableLiveData
LiveData
中使其可观察。然后通过更新这些选择中的项目,我可以触发必要的查询在大桌子上。

目前我的代码具有以下结构,我已在问题中将其精简为我认为相关的内容。最终我想在更复杂的查询中使用多个

keyset
。我的简化模型文件如下,

class Model(application : Application) : AndroidViewModel(application)
{
  val keys    : LiveData<List<Key>>
  val keyset  : LiveData<MutableList<Key>>
  val values  : LiveData<List<Value>>
  init {
    keys   = repository.keys
    values = repository.values
    keyset = mutableListOf<Key>() // I'm not entirely sure how to instantiate LiveData<MutableList<Key>>
  }
}

它依赖于存储库,

class Repository(private val queryset : QuerySet)
{
   val keys   : LiveData<List<Key>>   = queryset.getKeys()
   val values : LiveData<List<Value>> = queryset.getValues()
}

这依赖于查询集

@Dao
class QuerySet(application : Application) : AndroidViewModel(application)
{
  @Query("SELECT * FROM KeyEntity")
  fun getKeys() : LiveData<list<Key>>
  @Query("SELECT * FROM ValueEntity WHERE key in (:keys)")
  fun getValues(keys : MutableList<Key>) : LiveData<list<Value>>
}

Key
Value
类只是
KeyEntity
ValueEntity
的POJO,并且只需指定相同的字段。

为此目的我应该使用

MutableLiveData
还是
LiveData
?如果是这样,应该如何实施
keyset
?也许有更规范的方式来这样做?

kotlin android-livedata mutablelivedata mutablelist
2个回答
5
投票

LiveData 与 MutableLiveData

我不确定是否必须将

MutableList
包装为
LiveData<MutablList<POJO>>
还是
MutableLiveData<MutableList<POJO>>
,其中
POJO
是数据库实体或代理一个或多个数据库实体的数据类的实例。 Sneh Pandaya 简洁地解释了这两个类之间的区别。我也不确定如何实例化它们。以下创建实例,但
value
keyset
被初始化为
null
,并且必须为
MutableLiveData
设置初始值。

class Model(application : Application) : AndroidViewModel(application)
{ ...
  val keyset  : LiveData<MutableList<Key>>
  init { ...
    keyset = MutableLiveData<MutableList<Key>>() // Initialized as null
    keyset.value = mutableListOf<Key>()          // Assign an empty list
  ... }
... }

MutableLiveData
有一个细微差别,它没有正式封装数据。也就是说,当它包装项目时,它不会公开包装项目的方法,因为当包装项目被修改时,它自己会发出通知。它仅跟踪包装的物品何时被换出(参见Gznlt)。 Samnang CHEA 提供了一个很好的方法来支持这一点。

位置,位置,位置,...

我不确定在哪里正式放置

keyset
属性。 Android 文档 提供以下信息;事实证明我走在正确的道路上。

更新 LiveData 对象

LiveData 没有公开可用的方法来更新存储的数据。 MutableLiveData 类公开公开 setValue(T) 和 postValue(T) 方法,如果需要编辑存储在 LiveData 对象中的值,则必须使用这些方法。 通常 MutableLiveData 在 ViewModel 中使用,然后 ViewModel 只向观察者公开不可变的 LiveData 对象。

查询

我还没弄清楚的是如何触发

values
的更新。


3
投票

观察者仅在 LiveData 值发生变化时收到通知

LiveData 和 StateFlow 都是如此

当您声明

MutableLiveData<MutableList<Any>>
的实例,然后将值添加到包装在 MutableLiveData 中的列表中作为
variable.value.add(Any)
时,观察者将不会收到通知。它不会监听列表/模型内部内容更新的此类更改。

有不同的解决方法可以通过创建扩展来通知观察者,但这对于实现最简单的任务来说非常复杂。

最简单的方法如下:

private val _mobileTopUp = MutableLiveData<List<DataModel>>(emptyList())

然后创建一个简单的可变列表,您将在其中收集项目。您可以在函数顶部声明此列表,以便每次调用函数时它都会变空,以避免冗余数据。这完全取决于你

val list = mutableListOf<DataModel>()
list.add(it)
_mobileTopUp.value = list

现在,观察者将会收到通知,因为我们在这里将 list 设置为 LiveData 的值。

© www.soinside.com 2019 - 2024. All rights reserved.