I am new to Jetpack Compose and I just started trying it out by creating a timer application but I ran into a problem.
In my application each task has a different duration and after one of them is finished (the time has elapsed) then the next one should start. My problem is that my app works correctly only for the first task. After the first task is finished and the second one should be displayed the task title and description change but the timer's countdown value remains 0, it doesn't update from the previous state.
The onFinished calls one of the viewmodel's method that will fetch the next task that should be displayed and loads it into a livedata. I observe the changes on this livedata the following way:
val task = viewModel.currentTask.observeAsState().value
This task has a duration field that I pass to this Timer composable but when this task will be updated (because the livedata has a new value) the Timer composable doesn't recognize these changes. It doesn't restart the countdown, it stays 0.
I am not sure if I am understanding and using correctly the MutableState concept so can someone please help me?
@Composable
fun Timer(duration: Long, onFinished: () -> Unit) {
var currentTimerValue by remember { mutableStateOf(duration) }
LaunchedEffect(key1 = currentTimerValue) {
if (currentTimerValue > 0) {
delay(1000L)
currentTimerValue--
} else {
onFinished.invoke()
}
}
Text(text = currentTimerValue.toString(), fontSize = 24.sp, color = Color.White)
}
CodePudding user response:
The issue is here
var currentTimerValue by remember { mutableStateOf(duration) }
After Timer composable enters composition the block inside remember is initilized and it doesn't change unless you reset it with new key.
You can update it as
var currentTimerValue by remember(duration) { mutableStateOf(duration) }
which will reset to duration every time duration param of Timer function changes