I'm learning compose and as an exercise I'm trying to show a list of countdown timers. One button will add a new timer to the list, then for every timer on that list a lazycolumn will show a row with a text displaying the time of the countdown and a button to start the countdown.
Here i added three timers to the list and they all show up just fine:
Then when i start the countdown all the other rows get updated even though they are not being changed:
My viewmodel:
data class MyClass(val text: String, val isClickable: Boolean)
class VM : ViewModel() {
val myList = mutableStateListOf<MyClass>()
fun addTimer() {
myList.add(myList.size, MyClass("0", true))
}
fun changeText(index: Int, tempo: String) {
myList[index] = myList[index].copy(text = tempo)
}
fun changeIsClickable(index: Int, click: Boolean) {
myList[index] = myList[index].copy(isClickable = click)
}
}
My composable screen:
val viewModel: VM by viewModels()
(...)
@Composable
fun MainScreen(viewModel: VM) {
val scope = CoroutineScope(Dispatchers.Main)
Column(verticalArrangement = Arrangement.spacedBy(15.dp)) {
Row() {
Button(onClick = { viewModel.addTimer() }
) {
Text(text = "Add Timer")
}
}
LazyColumn {
itemsIndexed(viewModel.myList) { index, list ->
Row(modifier = Modifier.border(8.dp, randomColor())) {
Text(
text = list.text, modifier = Modifier
.padding(20.dp)
)
Button(
enabled = list.isClickable,
onClick = {
viewModel.changeIsClickable(index, false)
var currTime = Calendar.getInstance().timeInMillis
val endTime =
currTime + (7000L..20000L).random() //random between 7 and 20
scope.launch {
while (endTime > currTime) {
delay(100)
val timeTemporary =
((endTime - currTime) / 1000).toString() + "\n" + "Secs"
viewModel.changeText(index, timeTemporary)
currTime = Calendar.getInstance().timeInMillis
}
viewModel.changeText(index, "Done")
viewModel.changeIsClickable(index, true)
}
}) {
Text(text = "Start")
}
}
}
}
}
}
I've tried many suggestions like this one and this one (hence the colorful borders to check recomposing) but I cannot get the untouched rows not to update. What am I missing? How can I stop lazycolumn from updating when it shouldn't?