我目前有一个包含MyItem列表并使用Firebase / LiveData的项目.它分为几组,每个组都有项目.
如果发生以下任何情况,我希望能够更新此列表:
>一项已更新(通过Firebase在后端)
>过滤器已更改(每个用户在Firebase上的单独表)
>将项目添加为书签(在Firebase上每个用户一个单独的表)
为了获得目录列表,我有一个类似这样的函数来返回LiveData,该LiveData将在项目更新时更新(#1).
getList(id: String): LiveData<List<MyItem>> {
val data = MutableLiveData<List<MyItem>>()
firestore
.collection("groups")
.document(id)
.collection("items")
.addSnapshotListener { snapshot,exception ->
val items = snapshot?.toObjects(MyItem::class.java) ?: emptyList()
// filter items
data.postValue(items)
}
return data
}
在viewmodel中,我有处理这种情况的逻辑.
视图模型
private val result = MediatorLiveData<Resource<List<MyItem>>>()
private var source: LiveData<List<MyItem>>? = null
val contents: LiveData<Resource<List<MyItem>>>
get() {
val group = database.group
// if the selected group is changed.
return Transformations.switchMap(group) { id ->
// showing loading indicator
result.value = Resource.loading(null)
if (id != null) {
// only 1 source for the current group
source?.let {
result.removeSource(it)
}
source = database.getList(id).also {
result.addSource(it) {
result.value = Resource.success(it)
}
}
// how to add in source of filter changes?
} else {
result.value = Resource.init(null)
}
return@switchMap result
}
}
逻辑非常复杂,很难遵循.有没有更好的方法来构造它来处理多个不同的更改?存储用户当前过滤器的最佳方法是什么?
谢谢.
最佳答案
我不知道我是否正确回答了您的问题,但是如果您有一个可以使用一个列表(例如MyItemList之类)的视图,并且该列表在多种情况下已更新或更改,则必须使用MediatorLiveData.
我的意思是,您必须拥有三个LiveData,每个LiveData负责一种情况,以及一个MediatorLiveData,用于通知它们中的每一个是否已更改.
见下文:
fun getListFromServer(id: String): LiveData<List<MyItem>> {
val dataFromServer = MutableLiveData<List<MyItem>>()
firestore
.collection("groups")
.document(id)
.collection("items")
.addSnapshotListener { snapshot,exception ->
val items = snapshot?.toObjects(MyItem::class.java) ?: emptyList()
dataFromServer.postValue(items)
}
return dataFromServer
}
fun getFilteredData(id: String): LiveData<FilterData> {
return DAO.user.getFilteredData(id)
}
fun getBookmarkedList(id: String): LiveData<BookmarkData> {
return DAO.user.getBookmarkedData(id)
}
并且在viewmodel中,您有一个MediatorLiveData可以在这些liveData上进行观察,直到任何数据已更改通知视图为止.
private val result = MediatorLiveData<<List<MyItem>>()
fun observeOnData(id: String,owner: LifeCycleOwner,observer: Observer<List<MyItem>>) {
result.observe(owner,observer);
result.addSource(Database.getListFromServer(id),MyItemList -> {
if(MyItemList != null)
result.setValue(MyItemList)
});
result.addSource(Database.getFilteredData(id),filterData -> {
if(filterData != null) {
val myItemList = result.getValue()
if (myItemList == null) return
//here add logic for update myItemList depend On filterData
result.setValue(myItemList)
}
});
result.addSource(Database.getBookmarkedList(id),bookmarkData -> {
if(MyItemList != null) {
val myItemList = result.getValue()
if (myItemList == null) return
//here add logic for update myItemList depend On bookmarkData
result.setValue(myItemList)
}
});
}