Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

311
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda