Могу ли я обновить список в StateFlow (и изменить Compose View) без ручного создания нового только для изменения одного значения в списке?

У меня есть lazyColumn элемента todo

      data class TodoItem(val id: Int, val title: String, var urgent: Boolean = false)


class AppViewModel : ViewModel() {
    private var todoList = mutableListOf(
        TodoItem(0, "My First Task"),
        TodoItem(1, "My Second Task", true),
        TodoItem(2, "My Third Task")
    )
    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
    }
}

И мой lazyColumn, как показано ниже, где я могу обновитьurgentзначение соответственно

      @Composable
fun Greeting(name: String) {
    val todoListState = viewModel.todoListFlow.collectAsState()

    LazyColumn(modifier = Modifier.fillMaxHeight()) {
        items(items = todoListState.value, itemContent = { item ->
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    modifier = Modifier
                        .weight(1f)
                        .padding(8.dp),
                    text = item.title
                )
                Checkbox(
                    checked = item.urgent,
                    onCheckedChange = {
                        val index = todoListState.value.indexOf(item)
                        viewModel.setUrgent(index, it)
                    }
                )
            }
         })
    }
}

Все это работает нормально.

Но я чувствую, что функция ниже странная, где мне нужно создать новый список для обновления StateFlow.

          fun setUrgent(index: Int, value: Boolean) {
        val modified = todoList.toMutableList()
        modified[index] = modified[index].copy(urgent = value)
        todoList = modified
        _todoListFlow.value = modified
    }

Я не могу просто обновитьtodoListкак показано ниже, так как это не сработает

          fun setUrgent(index: Int, value: Boolean) {
        todoList[index] = todoList[index].copy(urgent = value)
        _todoListFlow.value = todoList
    }

Есть ли способ не создавать вручную измененный todoList для его обновления?

1 ответ

Я могу заставить его работать, преобразовав мойtodoListв моемViewModelиз списка вmutableStateListOf

         private var todoList = mutableStateListOf(
        TodoItem(0, "My First Task"),

Тогда я могу изменить

          fun setUrgent(index: Int, value: Boolean) {
        todoList[index] = todoList[index].copy(urgent = value)
    }

Также в моей функции создания мне больше не нужноcollectAsState()

      val todoListState = viewModel.todoListFlow

Несмотря на эту работу, мне кажется странным иметь MutableStateList в ViewModel и проходить через StateFlow.

Другие вопросы по тегам