Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 仅通过当前数据使用MediaLiveData的最佳实践_Android_Android Livedata - Fatal编程技术网

Android 仅通过当前数据使用MediaLiveData的最佳实践

Android 仅通过当前数据使用MediaLiveData的最佳实践,android,android-livedata,Android,Android Livedata,将MediatorLiveData与多个源一起使用的最佳实践是什么 我在ViewModel中有一个中介livedata,它是从数据的视图访问的,最终应该显示它 MediatorLiveData依赖于多个其他LiveData。其中一些来自存储库层,一些必须在ViewModel中处理,然后才能从MediaLiveData访问,还有一些来自视图 因此,我当前的实现类似于以下模式: public MyViewModel extends ViewModel { LiveData<Foo>

将MediatorLiveData与多个源一起使用的最佳实践是什么

我在ViewModel中有一个中介livedata,它是从数据的视图访问的,最终应该显示它

MediatorLiveData依赖于多个其他LiveData。其中一些来自存储库层,一些必须在ViewModel中处理,然后才能从MediaLiveData访问,还有一些来自视图

因此,我当前的实现类似于以下模式:

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*/
   });
}