将两个 LiveData 合并为一个 Android

问题描述

我需要合并这两个数据。他们都有自己的 Fragment、Dao、Model 和 Repository。并且两者都从不同的表返回不同的数据。

ItemFavourite 表存储 Item 和 Itemmoto 上方表的 id。

   public LiveData<Resource<List<Item>>> getItemFavouriteData() {
            return itemFavouriteData;
   }
  //Moto
   public LiveData<Resource<List<Itemmoto>>> getItemFavouriteDataMoto() {
  return itemFavouriteDataMoto;
  }

我就是这样试的。

public class Favouriteviewmodel extends PSviewmodel {

 private final LiveData<Resource<List<Item>>> itemFavouriteData;
 private final LiveData<Resource<List<Itemmoto>>> itemFavouriteDataMoto;
 private mutablelivedata<Favouriteviewmodel.TmpDataHolder> itemFavouriteListObj = new  
 mutablelivedata<>();
 private mutablelivedata<FavouriteMotoviewmodel.TmpDataHolder> itemFavouriteListObjMoto = new 
 mutablelivedata<>();


@Inject
Favouriteviewmodel(ItemRepository itemRepository,ItemmotoRepository itemmotoRepository) {

    itemFavouriteData = Transformations.switchMap(itemFavouriteListObj,obj -> {
        if (obj == null) {
            return AbsentLiveData.create();
        }
        Utils.psLog("itemFavouriteData");
        return itemRepository.getFavouriteList(Config.API_KEY,obj.userId,obj.offset);
    });


    itemFavouriteDataMoto = Transformations.switchMap(itemFavouriteListObjMoto,obj -> {
        if (obj == null) {
            return AbsentLiveData.create();
        }
        Utils.psLog("itemFavouriteData");
        return itemmotoRepository.getFavouriteList(Config.API_KEY,obj.offset);
    });

}

   public LiveData<Resource<List<Item>>> getItemFavouriteData() {
            return itemFavouriteData;
   }

   public LiveData<Resource<List<Itemmoto>>> getItemFavouriteDataMoto() {
   return itemFavouriteDataMoto;
   }

 private static LiveData<Resource<List<Item>>> mergeDataSources(LiveData... sources) {
    MediatorLiveData<Resource<List<Item>>> mergedSources = new MediatorLiveData();
    for (LiveData source : sources) {
        mergedSources.addSource(source,mergedSources::setValue);
    }
    return mergedSources;
}

public LiveData<Resource<List<Item>>> getFavourites() {
    return mergeDataSources(
            getItemFavouriteDataMoto(),getItemFavouriteData());
}

}

从 Fragment 我观察到的数据是这样的:

 LiveData<Resource<List<Item>>> news = favouriteviewmodel.getFavourites();


    if (news != null) {

        news.observe(this,listResource -> {
            if (listResource != null) {

                switch (listResource.status) {
                    case LOADING:
                        // Loading State
                        // Data are from Local DB

                        if (listResource.data != null) {
                            //fadeIn Animation
                            fadeIn(binding.get().getRoot());

                            // Update the data
                            replaceData(listResource.data);

                        }

                        break;

                    case SUCCESS:
                        // Success State
                        // Data are from Server

                        if (listResource.data != null) {
                            // Update the data
                            replaceData(listResource.data);
                        }

                        favouriteviewmodel.setLoadingState(false);

                        break;

                    case ERROR:
                        // Error State

                        favouriteviewmodel.setLoadingState(false);
                        favouriteviewmodel.forceEndLoading = true;

                        break;
                    default:
                        // Default

                        break;
                }

            } else {

                // Init Object or Empty Data

                if (favouriteviewmodel.offset > 1) {
                    // No more data for this list
                    // So,Block all future loading
                    favouriteviewmodel.forceEndLoading = true;
                }

            }

        });
    }

我获得的唯一数据仅来自 Item 表。

解决方法

您可以使用 MediatorLiveData 和元组,但从技术上讲,您也可以使用 this library I wrote for this specific purpose 为您完成它,并像这样解决它

import static com.zhuinden.livedatacombineutiljava.LiveDataCombineUtil.*;

private final LiveData<Pair<Resource<List<Item>>,Resource<List<ItemMoto>>>> favorites = combine(itemFavouriteData,itemFavouriteDataMoto,(favorites,favoriteMoto) -> {
    return Pair.create(favorites,favoriteMoto);
});

public LiveData<Pair<Resource<List<Item>>,Resource<List<ItemMoto>>>> getFavorites() {
    return favorites;
}
,

使用中介实时数据,我们可以观察到 2 个实时数据。

val groupChatFeed: LiveData<List<Feed<*>>> = MediatorLiveData<List<Feed<*>>>().apply {
    fun prepareDataAndSetStates(): List<Feed<*>> {
        val data: MutableList<Feed<*>> = mutableListOf()
        if (postList.value?.data?.isNullOrEmpty() == false) {
           data.addAll(postList.value?.data ?: emptyList())
        }
        if (connectionRecommendations.value?.data?.isNullOrEmpty() == false) {
           val recommendations = connectionRecommendations.value?.data?.toFeedItem()
           data.add(recommendations)
        }
        
        return data
    }

    addSource(postList) {
        value = prepareDataAndSetStates()
    }

    addSource(connectionRecommendations) {
        value = prepareDataAndSetStates()
    }
}

我们正在观察 2 个不同的实时数据 postListconnectionRecommendations

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...