ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android – 仅通过当前数据使用MediatorLiveData的最佳实践

2019-09-29 13:37:54  阅读:439  来源: 互联网

标签:android android-livedata


将MediatorLiveData与多个源一起使用的最佳做法是什么?

我在ViewModel中有一个MediatorLiveData,可以从最终显示的数据视图中访问.

MediatorLiveData依赖于多个其他LiveDatas.其中一些来自存储库层,其中一些必须在ViewModel中处理,然后才能从MediatorLiveData访问它们,其中一些来自View.

所以我当前的实现看起来像以下架构:

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
   }
}

通过这个实现我声明,输出LiveData的值是在每个LiveData出现后设置的.
在某些情况下,如果我留下一些空检查,我得到一个NullPointerException.
但是这个解决方案对我来说似乎有些混乱,因为对于我必须添加到ViewModel的每个LiveData,我必须将它添加到每个源代码中.

解决方法:

首先你需要一些元组:

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;
    }
}

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;
    }
}

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;
    }
}

一旦你有了元组,就可以编写类似于Transformations.map的辅助函数,除非你现在可以这样做:

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

标签:android,android-livedata
来源: https://codeday.me/bug/20190929/1831564.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有