How to convert LiveData<List<Foo>> into LiveData<List<Bar>>?

3.9k views Asked by At

Let's say we have two objects of LiveData:

LiveData<List<Foo>> fooList;
LiveData<List<Bar>> barList;

And by some method (or the constructor) Foo can be converted to the Bar object. What is the best way to convert the first observable, which has the list of Foo objects to the observable with the list of Bar objects.

I know that it is possible to do this:

barList = Transformations.map(fooList, fooList1 -> {
        List<Bar> barList = new ArrayList<>();
        for (Foo foo: fooList1) {
            barList.add(new Bar(foo)); 
        }
        return barList;
    });

But isn't there a better way similar to the flatMap operator in RxJava, by which we make all of the necessary conversions with the items from the list on the fly instead of dealing with the lists themselves as in the example above?

1

There are 1 answers

5
CommonsWare On BEST ANSWER

You can create your own transformation, following the recipe shown in the source to Transformations. FWIW, this sample app demonstrates a custom filter() implementation:

/***
 Copyright (c) 2017 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.

 Covered in detail in the book _Android's Architecture Components_
 https://commonsware.com/AndroidArch
 */

package com.commonsware.android.livedata;

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MediatorLiveData;
import android.arch.lifecycle.Observer;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

class LiveTransmogrifiers {
  interface Confirmer<T> {
    boolean test(T thingy);
  }

  @MainThread
  static <X> LiveData<X> filter(@NonNull LiveData<X> source,
                                @NonNull final Confirmer<X> confirmer) {
    final MediatorLiveData<X> result=new MediatorLiveData<>();

    result.addSource(source, new Observer<X>() {
      @Override
      public void onChanged(@Nullable X x) {
        if (confirmer.test(x)) {
          result.setValue(x);
        }
      }
    });

    return(result);
  }
}

Otherwise, no. LiveData is meant as a lightweight RxJava analogue that is lifecycle-aware. If you need lots of operators, you are better served using RxJava directly.