Search code examples
androidandroid-architecture-componentsandroid-livedataandroid-viewmodel

LiveData and Transformation usage


I've an Android app with these classes:

  • ListActivity displays all Item objects in a ListView

  • DetailActivity should display all the properties for an object, using another ListView

  • Item is my object which contains field1, field2, and so on

ListActivity passes to DetailActivity the itemId using an intent's extra parameter when the user click on a ListActivity item.

The flow should be:

  1. DetailActivity instantiate the DetailViewModel passing the itemId
  2. DetailViewModel get from the Repository the LiveData<Item> object identified by the provided itemId
  3. DetailViewModel creates a List<NameValueBean> using the LiveData<Item> fields (propertiesList.add(new NameValueBean("field1", item.getField1()); ...)
  4. DetailActivity observes the List<NameValueBean> and use it to feed the DetailAdapter which is the controller of the details ListView

The problem is that the List<NameValueBean> should be observable, so should be a LiveData<List<NameValueBean>>, created each time the LiveData<Item> changes.

How can I get that? I think there is a Transformation to do but I do not understand how implement it.


Solution

  • The Transformations.map function is your best bet to accomplish this.

    To give more context, Transformations.map will take a LiveData<T>, perform a transformation and turn it into a LiveData<Y>.

    The method takes a LiveData<T>, and a lambda who's purpose is to transform the value emitted by the LiveData, T, into a new value Y.

    Transformations.map will take the value emitted by a given LiveData<T> and map and return a LiveData<Y>.

    Note: This transformation will be done on the main thread.

    Source: https://developer.android.com/reference/android/arch/lifecycle/Transformations#map


    A quick answer:

    fun getNameValueBeanLiveData(itemId: Int): LiveData<List<NameValueBean> {
        val itemLiveData: LiveData<Item> = repository.getItemLiveData(itemId)
        return Transformations.map(itemLiveData) { item ->
            val nameValueBeanList = mutableListOf<NameValueBean>()
            return nameValueBeanList.apply {
                add("field1", item.field1)
                add("field2", item.field2)
                ...
            }.toList()
        }
    }