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.