elye
01/04/2023, 11:26 AMclass AppViewModel : ViewModel() {
private var todoList = listOf(
TodoItem(0, "My First Task"),
TodoItem(1, "My Second Task", true)
)
private val _todoListFlow = MutableStateFlow(todoList)
val todoListFlow: StateFlow<List<TodoItem>> get() = _todoListFlow
fun setUrgent(index: Int, value: Boolean) {
val modified = todoList.toMutableList()
modified[index] = modified[index].copy(urgent = value)
todoList = modified
_todoListFlow.value = modified
}
}
val viewModel = AppViewModel()
@Composable
fun MyTodoList {
val todoListState = viewModel.todoListFlow.collectAsState()
LazyColumn(modifier = Modifier.fillMaxHeight()) {
items(items = todoListState.value, itemContent = { item ->
Row {
Text(text = item.title)
Checkbox(
checked = item.urgent,
onCheckedChange = {
val index = todoListState.value.indexOf(item)
viewModel.setUrgent(index, it)
}
)
}
})
}
}
But I dislike to update a field in the list, I have to create a modify list to pass to the stateFlow.
fun setUrgent(index: Int, value: Boolean) {
val modified = todoList.toMutableList()
modified[index] = modified[index].copy(urgent = value)
todoList = modified
_todoListFlow.value = modified
}
I can fix it using Solution in https://stackoverflow.com/a/75004437/3286489, but feel it is wrong, as that solution is having MutableState in ViewModel.
I wonder how can I avoid the need to create the entire list to send through the StateFlow, if I just need to change a variable that update the compose view?Zun
01/04/2023, 1:04 PMMark Murphy
01/04/2023, 11:26 PMI can fix it using Solution inThat does not appear to be a solution to your problem. Your "problem" is:
I dislike to update a field in the list, I have to create a modify list to pass to the stateFlowThat seems to be what
SnapshotStateList does (see its mutate() function), and SnapshotStateList is what backs mutableStateListOf(). If your sole concern is that you feel that the code for updating an immutable list is ugly, implement an extension function that hides the ugly bits.