Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

310
Views
Android LiveData/StateFlow List Item Property Update Issue

So I'm updating my RecylerView with StateFlow<List> like following:

My data class:

data class Student(val name: String, var isSelected: Boolean)

My ViewModel logic:

fun updateStudentsOnSelectionChanged(targetStudent: Student) {
    val targetIndex = _students.value.indexOf(targetStudent)
    val isSelected = !targetStudent.isSelected

    _students.value[targetIndex].isSelected = isSelected        //<- doesn't work
} 

Problem: The UI is not changed, but the isSelected inside _student is changed, what's going on? (same to LiveData)

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

I assume _students is a StateFlow<List>. Changing the isSelected property of the Student model doesn't trigger the StateFlow. The workaround would be to make the isSelected property of the Student data class immutable to get it compared when new state is set, create a MutableList out of the current list and copy the existing Student object with the new value for isSelected property:

data class Student(val name: String, val isSelected: Boolean)

val students = _students.value.toMutableList()
students[targetIndex] = students[targetIndex].copy(isSelected = isSelected)
_students.value = students
over 4 years ago · Santiago Trujillo Report

0

Ok, thanks to @Tenfour04 and @Sergey, I finally found out that StateFlow/LiveData cannot detect the internal changes, that's because they are both actually comparing the Reference of the .value.

That means, If I want to force the StateFow<List> to update, the only way is to assign a new List to it, therefore I created the following helper extension function:

fun <T> List<T>.mapButReplace(targetItem: T, newItem: T) = map {
    if (it == targetItem) {
        newItem
    } else {
        it
    }
}

//this function returns a new List with the content I wanted

In Fragment:

val itemCheckAction: (Student) -> Unit = { student ->
    val newStudent = student.copy(isSelected = !student.isSelected)    //prepare a new Student

    viewModel.updateStudentsOnSelectionChanged(student, newStudent)    //update the StateFlow
}

In ViewModel:

fun updateStudentsOnSelectionChanged(currentStudent: Student, newStudent: Student) {
    val newList = _students.value.mapButReplace(currentStudent, newStudent)

    _students.value = newList       //assign a new List with different reference
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!