1

The Item.kt class is

@Entity(tableName = "item")
class Item(
    val id: Long,
    val title: String,
    ) {
    @Ignore
    var selection: Boolean = false
}

Then i make a query to get all the items in the table ,it return

LiveData<List<Item>>

Then in the viewModel i want to apply selection(true) accordig to the Mutablelivedata selectionId, the selection id contain MutableLiveData<Long> (it contain an id in the LiveData<List<Item>>)

The MyViewModel.kt code is look like this


class MyViewModel(val repository: Repository) : ViewModel() {
    ..........
    ......

    val selectionId: MutableLiveData<Long> by lazy {
        MutableLiveData<Long>()
    }

    fun setSelectionId(id: Long) {
        selectionId.postValue(id)
    }

    ..........
    ......

    val itemLiveList: LiveData<List<Item>> = liveData(Dispatchers.IO) {
        emitSource(repository.getItems())
    }
 }

If it is an List<Item> i can do somethig like this


 val ItemWithSelection: List<Item> = repository.getItems().apply {
        this.forEach {
            if (it.id == selectionId) {
                it.selection = true
            }
        }
    }

but i don't know how to achieve this using Mediator LiveData . Please help me

d-feverx
  • 1,424
  • 3
  • 16
  • 31

1 Answers1

1

I don't understand everything in your code, for example I have never seen a function called liveData(CoroutineDispatcher). But do you mean you want something like this?

val listWithoutSelection = liveData(Dispatchers.IO) {
    emitSource(repository.getItems())
}

val listWithSelection = MediatorLiveData<List<Item>>().apply {
    addSource(listWithoutSelection) { updateListSelection() }
    addSource(selectionId) { updateListSelection() }
}

fun updateListSelection() {
    listWithSelection.value = listWithoutSelection.value?.map {
        if (it.id == selectionId.value)
            it.copyWithSelection(true)
        else
            it
    }
}

The copyWithSelection could be easily done with Kotlin data classes. It is not needed dependent on whether you want to modify the object you get from the database. If you only use that object here, you could just always reset the selection of the others to false and then you can keep the object and you don't need a copy.

findusl
  • 2,454
  • 8
  • 32
  • 51
  • you treating liveData like normal list, to solve this problem we need ***MediatorLiveData*** but i don't know how to use in this situation – d-feverx Jul 02 '19 at 13:37
  • @d-feverx My example will set the selection correct when the list of items is first loaded. I treat it as a LiveData of list, that's why there is a `value` call in there. Do you mean you want it to update when the selection updates? It's not clear for me from the code samples, because you only set it.selection to true but never to false if it changes. – findusl Jul 02 '19 at 13:42
  • Yes i want itemLive List to update when the selection update,that is why i make selection id is of type mutableLivedata – d-feverx Jul 02 '19 at 13:54
  • @d-feverx I see. I changed my solution to use MediatorLiveData. I think I understood what you mean. You might want to make it clear in your question. – findusl Jul 02 '19 at 14:42