Search code examples
androidkotlinmvvmandroid-recyclerviewviewmodel

How can I update a recycler view of elements from my view model?


How can I update a recycler view of elements from my view model?

ViewModel

class HandlerViewModel(application: Application): AndroidViewModel(application) {

    fun update(data: Data, isActive: Boolean) {
        // calls a helper function that calls the backend then returns true or false.
        val result: Boolean = callBackend(data, isActive)
    }
}

So when the user clicks an item on the recycler view I will call this update() function. I want to then change the color of the item on the list depending on the result I get from the backend. How should I use LiveData to do that?

Normally if it is only one static element I can do it easily but if this is a recycler view of size n then how could I link it to LiveData?


Solution

  • If you're not using databinding, you can try something like this. Create a new field inside your data object that represents the boolean value for the alternative color. So in your adapter you can do this in you onBind:

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        val data = adapterList[position]
    
        if(data.otherColor) {
            viewholder.textView.color = Color.Red
        } else {
            viewholder.textView.color = Color.Black
        }
    }
    

    And Then:

    // inside your viewModel
    private val _singleData = MutableLiveData<Data>()
    val singleData: LiveData<Data>
        get() = _singleData
    
    fun update(data: Data, isActive: Boolean) {
        val result: Boolean = callBackend(data, isActive)
        data.otherColor = result
        _singleData.value = data
    }
    
    // inside your activity
    handlerViewModel.singleData.observe(this, Observer { singleData ->
        val index = adapter.adapterList.indexOfFirst { singleData.id == it.id }
        adapterList[index] = singleData
        adapter.notifyItemChanged(index)
    }
    

    Or if you want to observe and update the whole dataset:

    // inside your viewModel
    private val _allData = MutableLiveData<List<Data>>()
    val allData: LiveData<List<Data>>
        get() = _allData
    
    fun update(data: Data, isActive: Boolean) {
        val result: Boolean = callBackend(data, isActive)
    
        val listToUpdate = allData.value
        listToUpdate.find { it.id == data.id }.otherColor = result
    
        _allData.value = listToUpdate
    }
    
    // inside your activity
    handlerViewModel.allData.observe(this, Observer { rvData ->
        adapter.clear()
        adapter.addAll(rvData)
        adapter.notifydatasetChanged()
    }