繁体   English   中英

将两个 LiveData 合二为一 Android

[英]Combine Two LiveData into one 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.userId, 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 和元组,但从技术上讲,您也可以使用我为此特定目的编写的这个库,它为您完成它,并像这样解决它

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 个不同的 livedata postListconnectionRecommendations

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM