1

I am quite new to Jetpack compose and have an issue that my list is not recomposing when a property of an object in the list changes. In my composable I get a list of available appointments from my view model and it is collected as a state.

// AppointmentsScreen.kt
@Composable
internal fun AppointmentScreen(
    navController: NavHostController
) {
    val appointmentsViewModel = hiltViewModel<AppointmentViewModel>()
    val availableAppointments= appointmentsViewModel.appointmentList.collectAsState()
    
    AppointmentContent(appointments = availableAppointments, navController = navController)
}

In my view model I get the data from a dummy repository which returns a flow.

// AppointmentViewModel.kt

private val _appointmentList = MutableStateFlow(emptyList<Appointment>())
val appointmentList : StateFlow<List<Appointment>> = _appointmentList.asStateFlow()

init {
    getAppointmentsFromRepository()
}

// Get the data from the dummy repository
private fun getAppointmentsFromRepository() {
        viewModelScope.launch(Dispatchers.IO) {
            dummyRepository.getAllAppointments()
                .distinctUntilChanged()
                .collect { listOfAppointments ->
                if (listOfAppointments.isNullOrEmpty()) {
                    Log.d(TAG, "Init: Empty Appointment List")
                } else {
                    _appointmentList.value = listOfAppointments
                }
            }
        }
}


// dummy function for demonstration, this is called from a UI button
fun setAllStatesToPaused() {
    dummyRepository.setSatesInAllObjects(AppointmentState.Finished)
    // Get the new data
    getAppointmentsFromRepository()
}
 

Here is the data class for appointments

// Appointment data class
data class Appointment(
    val uuid: String,
    var state: AppointmentState = AppointmentState.NotStarted,
    val title: String,
    val timeStart: LocalTime,
    val estimatedDuration: Duration? = null,
    val timeEnd: LocalTime? = null
)

My question: If a property of one of the appointment objects (in the view models variable appointmentList) changes then there is no recomposition. I guess it is because the objects are still the same and only the properties have changed. What do I have to do that the if one of the properties changes also a recomposition of the screen is fired?

For example if you have realtime app that display stocks/shares with share prices then you will probably also have a list with stock objects and the share price updates every few seconds. The share price is a property of the stock object so this quite a similiar situation.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
xshake
  • 345
  • 3
  • 12
  • Afaik it should be a different object if one of the properties is changed. As an alternative, you can try to use `MutableState` instead of `MutableStateFlow`. Can you, please, also post AppointmentContent? – Marat Mar 31 '22 at 18:34
  • Don't use `var` properties in data classes and update it with `copy` method. More details in [this answer](https://stackoverflow.com/a/71629294/3585796) – Phil Dukhov Apr 01 '22 at 02:40

0 Answers0