Android mediator实时数据将2个实时数据合并为一个流和一个触发器
我有2个实时数据,我将它们作为源添加到中介实时数据中,我从视图模型中公开这些数据,以供片段观察 当任何一个实时数据更改时,它会触发中介实时数据的onChanged方法,这意味着我的观察者会被触发两次,我想要的是将两者结合起来,只观察一个只触发一次的流,我是否缺少什么,或者我需要为此使用自己的方法?目前我这样做,会触发两次 为了简洁起见删除了一些代码Android mediator实时数据将2个实时数据合并为一个流和一个触发器,android,android-livedata,android-viewmodel,mediatorlivedata,Android,Android Livedata,Android Viewmodel,Mediatorlivedata,我有2个实时数据,我将它们作为源添加到中介实时数据中,我从视图模型中公开这些数据,以供片段观察 当任何一个实时数据更改时,它会触发中介实时数据的onChanged方法,这意味着我的观察者会被触发两次,我想要的是将两者结合起来,只观察一个只触发一次的流,我是否缺少什么,或者我需要为此使用自己的方法?目前我这样做,会触发两次 为了简洁起见删除了一些代码 public CardViewModel(@NonNull Application application , int clicks, String
public CardViewModel(@NonNull Application application , int clicks, String[] cardArgs){
sentenceRepository = new SentenceRepository(application);
cards = Transformations.switchMap(search, mySearch -> sentenceRepository.searchLiveCardListByWordTypeAndWordDescriptionAndSearchWord(cardArgs[0],cardArgs[1],mySearch));
groupRepository = new GroupRepository(application);
groups = groupRepository.getGroupsByWordDescriptionAndWordType(cardArgs[0],cardArgs[1]);
sentencesAndGroups = new MediatorLiveData<>();
sentencesAndGroups.addSource(cards, sentences -> {
Log.d(TAG,"addSource cards");
sentencesAndGroups.setValue(combineLatest(sentences, groups.getValue()));
});
sentencesAndGroups.addSource(groups, groupsWithSentences -> {
Log.d(TAG,"addSource groups");
sentencesAndGroups.setValue(combineLatest(cards.getValue(), groupsWithSentences));
});
}
private List<Visitable> combineLatest(List<Sentence> sentenceList, List<GroupsWithSentences> groupsWithSentences) {
List<Visitable> visitableList = new ArrayList<>();
if (sentenceList != null){
visitableList.addAll(sentenceList);
}
if (groupsWithSentences != null){
visitableList.addAll(groupsWithSentences);
}
return visitableList;
}
公共CardViewModel(@NonNull应用程序,int单击,字符串[]cardArgs){
sentenceRepository=新的sentenceRepository(应用程序);
cards=Transformations.switchMap(搜索,mySearch->sentenceRepository.SearchLiveCardListByWordTypeandWordDescription和SearchWord(cardArgs[0],cardArgs[1],mySearch));
groupRepository=新的groupRepository(应用程序);
groups=groupRepository.getgroupsbyworddescription和wordtype(cardArgs[0],cardArgs[1]);
sentencesAndGroups=新的MediatorLiveData();
句子和组。添加来源(卡片、句子->{
日志d(标签“添加源卡”);
setValue(combineTest(句子,groups.getValue());
});
语句和组。添加源(组、组和句子->{
Log.d(标记“addSource组”);
setValue(组合测试(cards.getValue(),groupswith句子));
});
}
私有列表组合测试(列表句子列表、列表组和句子){
List visitableList=新建ArrayList();
if(语句列表!=null){
visitableList.addAll(句子列表);
}
if(groupswith句子!=null){
visitableList.addAll(Groupswith句子);
}
返回可访问列表;
}
有什么帮助吗?您可以使用
双功能。在我的项目中,我有一个包含以下内容的类:
public class MultipleLiveDataTransformation {
@MainThread
public static <X, Y, O> LiveData<O> biMap(LiveData<X> data1, LiveData<Y> data2, final BiFunction<X, Y, O> biFun) {
final MediatorLiveData<O> result = new MediatorLiveData<>();
result.addSource(data1, x -> result.setValue(biFun.apply(x, data2.getValue())));
result.addSource(data2, y -> result.setValue(biFun.apply(data1.getValue(), y)));
return result;
}
}
这里的问题是,每次最新的实时数据发出值时,它都会更新,因此它总是会触发两次,因为实时数据永远不会同时完成,我想要的可能是检查一个是否完成,然后超时,告诉实时数据它是否应该完成并发出一个值,或者等待其他实时数据完成,因为我只希望一个流(如throttle)在RxJavaServer上工作,那么我认为这不适合您的问题。这将在组或句子更新时触发。如果组
或句子
为空,您可以在biMap中返回一个空列表。如果它们都已填写,则可以将它们合并并返回完整列表。在更新之前,可以调用getVisitables()并检查列表是否为空。yh这主意不错
public LiveData<Visitable> getVisitables() {
return MultipleLiveDataTransformation.biMap(groups, sentences, (gro, sen) -> {
List<Visitable> visitableList = new ArrayList<>();
if (gro != null) {
visitableList.addAll(gro);
}
if (sen != null) {
visitableList.addAll(sen);
}
return visitableList;
});
}
public LiveData<Visitable> getVisitables() {
return MultipleLiveDataTransformation.biMap(groups, sentences, (gro, sen) -> {
List<Visitable> visitableList = new ArrayList<>();
if (gro != null && !gro.isEmpty() && sen != null && !sen.isEmpty()) {
visitableList.addAll(gro);
visitableList.addAll(sen);
}
return visitableList;
});
}