First you need some tuples:
public class Tuple2<S, T> {
public final S first;
public final T second;
public Tuple2(S first, T second) {
this.first = first;
this.second = second;
}
}
and
public class Tuple3<S, T, U> {
public final S first;
public final T second;
public final U third;
public Tuple3(S first, T second, U third) {
this.first = first;
this.second = second;
this.third = third;
}
}
and
public class Tuple4<S, T, U, V> {
public final S first;
public final T second;
public final U third;
public final V fourth;
public Tuple4(S first, T second, U third, V fourth) {
this.first = first;
this.second = second;
this.third = third;
this.fourth = fourth;
}
}
Once you have your tuples, you can write helper functions that work akin to Transformations.map
except now you could do:
public class LiveDataTransformations {
private LiveDataTransformations() {}
public static <S, T> LiveData<Tuple2<S,T>> ifNotNull(LiveData<S> first, LiveData<T> second) {
MediatorLiveData<Tuple2<S, T>> mediator = new MediatorLiveData<>();
mediator.addSource(first, (_first) -> {
T _second = second.getValue();
if(_first != null && _second != null) {
mediator.setValue(new Tuple2(_first, _second));
}
});
mediator.addSource(second, (_second) -> {
S _first = first.getValue();
if(_first != null && _second != null) {
mediator.setValue(new Tuple2(_first, _second));
}
});
return mediator;
}
public static <S, T, U> LiveData<Tuple3<S,T,U>> ifNotNull(LiveData<S> first, LiveData<T> second, LiveData<U> third) {
MediatorLiveData<Tuple3<S, T, U>> mediator = new MediatorLiveData<>();
mediator.addSource(first, (_first) -> {
T _second = second.getValue();
U _third = third.getValue();
if(_first != null && _second != null && _third != null) {
mediator.setValue(new Tuple3(_first, _second, _third));
}
});
mediator.addSource(second, (_second) -> {
S _first = first.getValue();
U _third = third.getValue();
if(_first != null && _second != null && _third != null) {
mediator.setValue(new Tuple3(_first, _second, _third));
}
});
mediator.addSource(third, (_third) -> {
S _first = first.getValue();
T _second = second.getValue();
if(_first != null && _second != null && _third != null) {
mediator.setValue(new Tuple3(_first, _second, _third));
}
});
return mediator;
}
public static <S, T, U, V> LiveData<Tuple4<S,T,U, V>> ifNotNull(LiveData<S> first, LiveData<T> second, LiveData<U> third, LiveData<V> fourth) {
MediatorLiveData<Tuple4<S, T, U, V>> mediator = new MediatorLiveData<>();
mediator.addSource(first, (_first) -> {
T _second = second.getValue();
U _third = third.getValue();
V _fourth = fourth.getValue();
if(_first != null && _second != null && _third != null && _fourth != null) {
mediator.setValue(new Tuple4(_first, _second, _third, _fourth));
}
});
mediator.addSource(second, (_second) -> {
S _first = first.getValue();
U _third = third.getValue();
V _fourth = fourth.getValue();
if(_first != null && _second != null && _third != null && _fourth != null) {
mediator.setValue(new Tuple4(_first, _second, _third, _fourth));
}
});
mediator.addSource(third, (_third) -> {
S _first = first.getValue();
T _second = second.getValue();
V _fourth = fourth.getValue();
if(_first != null && _second != null && _third != null && _fourth != null) {
mediator.setValue(new Tuple4(_first, _second, _third, _fourth));
}
});
mediator.addSource(fourth, (_fourth) -> {
S _first = first.getValue();
T _second = second.getValue();
U _third = third.getValue();
if(_first != null && _second != null && _third != null && _fourth != null) {
mediator.setValue(new Tuple4(_first, _second, _third, _fourth));
}
});
return mediator;
}
}
Now you can do
LiveData<???> liveDataForView;
private void setupForView() {
LiveData<Tuple3<Foo, Bar, FooBar>> intermediate = LiveDataTransformations.ifNotNull(liveData1, liveData2, liveData3);
liveDataForView = Transformations.map(intermediate, (tuple) -> {
Foo foo = tuple.first;
Bar bar = tuple.second;
FooBar fooBar = tuple.third;
return /*Some combinations of the LiveDatas*/
});
}
EDIT: You can use the library https://github.com/Zhuinden/livedata-combinetuple-kt to do the same thing.