Search code examples
kotlinnavigationandroid-jetpack-composemutablelivedata

mutableStateListOf is not updating it value on changing it


I have a todo app that reads to mutableStateListOf data from a view model. When Adding a todoItem it is working properly fine also by deleting it works fine state is getting updated by when I update the object it does not update its state.

But when I navigate to details screen it recomposes the UI then checklist gets updated given is the code

package com.example.todoapp.data

import androidx.compose.runtime.mutableStateListOf
import androidx.lifecycle.ViewModel

class TodoData : ViewModel() {
 private val todoData = mutableStateListOf<Todo>()
 var getTodoList: List<Todo> = todoData
 
 // WORKING FINE
 fun addTodoItem(todo: Todo) {
     todoData.add(todo)
 }
 
 // NOT WORKING BUT WORKS WHEN NAVIGATE TO A NEW COMPOSE AND RETURN BACK
 fun updateStatus(todo: Todo, checked: Boolean = false) {
    todoData.find { it == todo }?.let { task ->
         task.isChecked = checked
     }
 }

 // WORKING FIN
 fun deleteItem(todo: Todo) {
    todoData.remove(todo)
 }
}

Solution

  • The way State detects that an item changed is by comparing the previous instance of the value item to the new instance. Since you are reusing the same instance and merely changing its isChecked property, the old value and new value are identical so it doesn’t detect any change. For this reason, mutable classes are not suitable for using as the type for a State.

    You should change the Todo class to be immutable (only vals, not vars). When you want to change the value, create a copy of the previous value that has the change.

    fun updateStatus(todo: Todo, checked: Boolean = false) {
        todoData[todoData.indexOf(todo)] =
            todo.copy(isChecked = checked)
    }