将不同的依赖 LiveData 对象合并为一个

Merging different depending LiveData objects into one

这是我的问题。 我必须将来自三个不同 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;
...
}

持有特定信息的RatingProduct对象。

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
...
}

任务是将 UserRatingRatingProduct 的所有数据收集到一个 RatedProduct 中,但隐藏了必要的步骤。

我认为最好的方法是使用三个不同的 LiveData 对象并在 MediatorLiveData

的帮助下合并它们

但我不确定如何以正确的方式执行此操作。我有点卡住了。我知道如何将 UserRatingLiveData 作为源添加到 MediatorLiveData 但我不知道如何添加其余两个,将它们称为 RatingLiveDataProductLiveData 关于键包含在 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
    )
}