android - 将不同的依赖 LiveData 对象合并为一个
问题描述
这是我的问题。我必须将三个不同LiveData
对象的数据生成到一个对象中。其中两个取决于其中之一。仅当收到所有三个对象数据时才应触发观察者。
这是一个例子:
生成的对象包含产品信息和该产品的特定评论评级。结果对象如下所示:
public class RatedProduct {
private String productKey; // database key to the product
private String ratingKey; // database key to the specific rating
private Product product; // the product information
private Rating rating; // the specifiv rating information
private HashMap<String, Boolean> customTags; // list of tags
...
}
源分布在不同的数据库位置。
第一个对象UserRating
包含附加数据 ( customTags
) 和只有两个键,引用产品和评级信息。
public class UserRating {
private String ratingKey;
private String productKey;
private HashMap<String, Boolean> customTags;
...
}
Rating
和Product
持有特定信息的对象。
public class Rating {
private float value; // value of the rating
private String productKey; // database key to the product
private String ratingComment;
...
}
public class Product {
private String name; // name of the product
private HashMap<String, Boolean> ratings; // list of all ratings
...
}
任务是将所有数据从 和 收集UserRating
到一个Rating
,但隐藏必要的步骤。Product
RatedProduct
我认为最好的方法是使用三个不同的LiveData
对象并在MediatorLiveData
但我不确定如何以正确的方式做到这一点。我有点卡住了。我知道如何将UserRatingLiveData
as 源添加到,MediatorLiveData
但我不知道如何添加剩余的两个,调用它们RatingLiveData
以及ProductLiveData
关于UserRatingLiveData
.
第二个问题是,MediatorLiveData<RatedProduct>
只有在检索到所有数据而不是其中一个时才应该更新。
这就是我所拥有的(或多或少没有)。LiveData<RatedProduct> getRatedProductLiveData()
我猜有趣的部分是:
public class UserViewModel extends ViewModel {
...
private UserRatingsLiveData mUserRatingsLiveDate;
public UserViewModel() {
//
// Getting current user
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
if (mUser != null) {
this.mUserRatingsLiveDate =
new UserRatingsLiveData(
mUsersDatabaseReference.child(mUser.getUid() + "/" + DB_PATH_RATINGS));
} else {
Log.d(LOG_TAG, "mUser is NULL");
}
}
@NonNull
public LiveData<RatedProduct> getRatedProductLiveData() {
final MediatorLiveData<RatedProduct> liveDataMerger = new MediatorLiveData<> ();
final UserRating receivedUserRating = new UserRating();
liveDataMerger.addSource(this.mUserRatingsLiveDate, new Observer<UserRating>() {
public void onChanged(UserRating userRatings) {
}
});
return liveDataMerger;
}
}
作为附加提示:数据库是 Firebase RealTimeDatabase,如果这有帮助的话。
解决方案
试试这样:
class MyViewModel {
val mainLiveData: LiveData<CustomClass> get() = _mainLiveData
private val firstLiveData = MutableLiveData<String>()
private val secondLiveData : MutableLiveData<Int>? = null
private val thirdLiveData : MutableLiveData<Long>? = null
private val _mainLiveData = MediatorLiveData<CustomClass>().also { mergeLiveData ->
mergeLiveData.addSource(firstLiveData) {
if (secondLiveData != null ) mergeLiveData.removeSource(secondLiveData)
if (thirdLiveData != null) mergeLiveData.removeSource(thirdLiveData)
secondLiveData = getSecondLiveData(firstLiveData.value)
thirdLiveData = getThirdLiveData(firstLiveData.value)
mergeLiveData.addSource(secondLiveData) {
updateMainLiveData(mergeLiveData)
}
mergeLiveData.addSource(thirdLiveData) {
updateMainLiveData(mergeLiveData)
}
}
}
private fun updateMainLiveData(mainLiveData: MediatorLiveData<CustomClass>) {
val first = firstLiveData.value ?: return
val second = secondLiveData.value ?: return
val third = thirdLiveData.value ?: return
mainLiveData.value = CustomClass(first, second, third)
}
data class CustomClass(
val first: String,
val second: Int,
val third: Long
)
}
推荐阅读
- c# - C# 有类似 Pascal 记录类型的东西吗?
- python-3.x - 覆盖列表(对象)
- python - 如果用户输入字符串而不是整数,我如何使代码重新运行
- java - 如何将其定向到正确的位置?
- c# - 如何以编程方式更改IP地址?
- javascript - Alexa 技能 .getResponse() 有什么作用?
- ruby - Ruby 递归索引/搜索方法(使用中间比较)返回不正确的索引值
- javascript - How to sink field value to nested JSON with lodash
- json - 如何使Vue显示来自json文件的本地路径的图像
- ibm-watson - 是否可以在 Watson 助手中获取 Slack 用户名作为实体?