Android 仅通过当前数据使用MediaLiveData的最佳实践
将MediatorLiveData与多个源一起使用的最佳实践是什么 我在ViewModel中有一个中介livedata,它是从数据的视图访问的,最终应该显示它 MediatorLiveData依赖于多个其他LiveData。其中一些来自存储库层,一些必须在ViewModel中处理,然后才能从MediaLiveData访问,还有一些来自视图 因此,我当前的实现类似于以下模式:Android 仅通过当前数据使用MediaLiveData的最佳实践,android,android-livedata,Android,Android Livedata,将MediatorLiveData与多个源一起使用的最佳实践是什么 我在ViewModel中有一个中介livedata,它是从数据的视图访问的,最终应该显示它 MediatorLiveData依赖于多个其他LiveData。其中一些来自存储库层,一些必须在ViewModel中处理,然后才能从MediaLiveData访问,还有一些来自视图 因此,我当前的实现类似于以下模式: public MyViewModel extends ViewModel { LiveData<Foo>
public MyViewModel extends ViewModel {
LiveData<Foo> liveData1;
LiveData<Bar> liveData2;
LiveData<FooBar> liveData3;
//Some other LiveDatas
MediatorLiveData liveDataForView
public MyViewModel() {
liveDataForView = new MediatorLiveData();
//Do some preprocessing with some of the LiveData
setupForView();
}
public MediatorLiveData getLiveDataForView() {
return liveDataForView;
}
private void setupForView() {
liveDataForView.addSource(liveData1, (foo -> {
if(liveData1.getValue() != null && liveData2.getValue() != null && liveData3.getValue() != null /*&& some other LiveData-checks*/)
liveDataForView.setValue(/*Some combinations of the LiveDatas*/);
}));
//Add sources to the MediatorLiveData for any other LiveData
}
}
公共MyViewModel扩展了ViewModel{
LiveData-liveData1;
LiveData-liveData2;
LiveData-liveData3;
//其他一些LiveData
MediatorLiveData liveDataForView
公共MyViewModel(){
liveDataForView=new MediatorLiveData();
//对一些LiveData进行一些预处理
setupForView();
}
公共中介LiveData getLiveDataForView(){
返回liveDataForView;
}
私有void setupForView(){
liveDataForView.addSource(liveData1,(foo->{
if(liveData1.getValue()!=null&&liveData2.getValue()!=null&&liveData3.getValue()!=null/*&其他一些LiveData检查*/)
setValue(/*LiveDatas*/)的一些组合;
}));
//为任何其他LiveData向MediatorLiveData添加源
}
}
在这个实现中,我断言输出LiveData的值是在每个LiveData出现之后设置的。
在某些情况下,如果我保留了一些null检查,就会得到一个NullPointerException。
但是这个解决方案对我来说似乎有点混乱,因为对于我必须添加到ViewModel的每个LiveData,我必须将其添加到每个源。您不必将其添加到每个源的每个表达式,因为您没有访问lambda表达式中的变量foo。
因此,您可以从所有lambda表达式调用helper函数(或者您甚至可以对所有源重复使用相同的lambda表达式,无法测试该atm。),这样您只需在单个helper函数中定义检查。首先,您需要一些元组:
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;
}
}
现在你可以做了
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*/
});
}
LiveData-liveDataForView;
私有void setupForView(){
LiveData intermediate=LiveDataTransformations.ifNotNull(liveData1、liveData2、liveData3);
liveDataForView=Transformations.map(中间,(元组)->{
Foo-Foo=tuple.first;
Bar=tuple.second;
FooBar FooBar=tuple.third;
return/*LiveDatas的一些组合*/
});
}
编辑:您可以使用库做同样的事情。谢谢您的回答。因此,如果我理解正确:如果我必须在实现时添加一些进一步的LiveData,我必须添加一个新的元组类,在该类中,我将xth LiveData添加到中介,然后调整setupForView以处理xth元素?是的,但它是。可能会生成一个更智能的方法来处理任何N数组,只要
vararg
LiveData可以映射到具有相同算术性的元组中。这样你就不用打字太多了。zipArray的方法给了我这个想法。
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;
}
}
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;
}
}
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*/
});
}