I'm facing sporadical issues with jetpack compose's mutable states. In a viewModel I'have a variable of type data class.
var headerState by mutableStateOf(ModelTemplateHeaderUiModel())
private set
When I update the variable in the viewModel with
headerState = headerState.copy(
client = RepoManager.getClientById(clientID) ?: Client(),
reportNumber = (RepoManager.getLastReportNumberByClient(clientID))?.plus(1)
?.toString()
?: ""
)
the states of client and reportNumber are updated but seem that the UI is not receiving the new state signal to update the Ui and the recomposition do not happens.
The state is used in this section :
Header(
viewModel.headerState,
onContractNumberChange = { viewModel.updateContractNumber(it) },
onReportNumberChange = { viewModel.updateReportNumber(it) },
onDateChange = { viewModel.updateDate(it) },
)
Header is defined as :
@Composable
fun Header(
headerState: ModelTemplateHeaderUiModel = ModelTemplateHeaderUiModel(),
onContractNumberChange: (String) -> Unit,
onReportNumberChange: (String) -> Unit,
onDateChange: (LocalDate) -> Unit,
)
ModelTemplateHeaderUiModel is defined as :
@Parcelize
data class ModelTemplateHeaderUiModel(
var descriptionHeader: String = "",
var client: Client = Client(),
var contractNumber: String = "",
var reportNumber: String = "",
var date: Long = Clock.System.now().epochSeconds
) : Parcelable
the strangest thing is that the variables whose update is not heard are only 3 :
contractNumber
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = headerState.contractNumber,
onValueChange = { onContractNumberChange(it) },
singleLine = true,
placeholder = { Text(text = "Contratto n°", color = Color.Gray) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
label = { Text(text = "Contratto n°") }
)
reportNumber
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = headerState.reportNumber, onValueChange = { onReportNumberChange(it) },
singleLine = true,
placeholder = { Text(text = "Rapporto di lavoro n°", color = Color.Gray) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
label = { Text(text = "Rapporto di lavoro n°") }
)
and client
Column(
verticalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.weight(1f)
) {
Text(text = "Cliente", style = MaterialTheme.typography.titleLarge)
Text(text = headerState.client.name, style = MaterialTheme.typography.titleMedium)
Text(text = headerState.client.address)
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp),
) {
Text(text = headerState.client.cap)
Text(text = headerState.client.city)
Text(text = headerState.client.province)
}
}
DescriptionHeader and date are updated correctly in the viewModel by :
fun loadModelById(modelID: String) {
viewModelScope.launch {
modelState.value = RepoManager.getCompleteModelById(modelID) ?: Model()
//update components
components.clear()
components.addAll(modelState.value.components)
//update header state
headerState = headerState.copy(descriptionHeader = modelState.value.headerDescription)
}
}
fun updateDate(value: LocalDate) {
headerState =
headerState.copy(date = value.atStartOfDayIn(TimeZone.currentSystemDefault()).epochSeconds)
}
So there is no difference in the method to update the state of the object.
I did some checks through the debugger and actually the data from firebase arrives, the variable is loaded correctly, the status is updated but the new data is not displayed. I don't understand how the same method of updating data works only for some variables and not for others. I want to clarify that there are no strange logics that manipulate the data that is not displayed. All data comes straight to the UI without manipulation.
I'm using
implementation 'androidx.core:core-ktx:1.8.0'
implementation "androidx.compose.ui:ui:1.3.0-alpha01"
implementation 'androidx.compose.compiler:compiler:1.2.0'
implementation 'androidx.compose.material3:material3:1.0.0-alpha14'
implementation "androidx.compose.ui:ui-tooling-preview:1.3.0-alpha01"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.0'
implementation 'androidx.activity:activity-compose:1.5.0'
implementation 'androidx.navigation:navigation-runtime-ktx:2.5.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.3.0-alpha01"
debugImplementation "androidx.compose.ui:ui-tooling:1.3.0-alpha01"
debugImplementation "androidx.compose.ui:ui-test-manifest:1.3.0-alpha01"
minSdk 26
targetSdk 32
jvmTarget = '1.8'
compose_version = '1.2.0'
plugins {
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
}
Anyone have any suggestions? Thank you