Объяснение критериев выбросов MutableStateFlowAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Объяснение критериев выбросов MutableStateFlow

Сообщение Anonymous »

Я пишу простое приложение todo, используя Compose и Stateflow.

Код: Выделить всё

data class Task(
val name: String,
val isCompleted: Boolean,
val date: Long
)
class SomeViewModel : ViewModel() {

private val _tasks = MutableStateFlow(listOf())
val tasks = _tasks.asStateFlow()
val todo = mutableListOf(
Task("Mop floor", false, System.currentTimeMillis()),
Task("Buy soap", true, System.currentTimeMillis()+1),
Task("Oranize toolbox", false, System.currentTimeMillis()+2)
)

init {
initialize(todo)
}

fun initialize(todo: List) {
_tasks.value = todo
}

fun toggleState(task: Task) {
val updatedList = todo.map {
if (it.name == task.name) task.copy(isCompleted = !it.isCompleted)
else it
}
todo.clear()
todo.addAll(updatedList)
_tasks.value = todo
}
Мой составной объект не смог получить обновление

Код: Выделить всё

class SomeFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = content {
MaterialTheme {
MainContent()
}
}
}

@Composable
private fun MainContent() {
val viewModel: SomeViewModel = viewModel()

Box(modifier = Modifier.fillMaxSize()) {
val tasks = viewModel.tasks.collectAsStateWithLifecycle().value
ToDoList(tasks, viewModel)
}
}

@Composable
private fun ToDoList(todoList: List, vm: SomeViewModel) {
LazyColumn {
items(todoList) { task ->
ToDoRow(task, vm)
}
}
}

@Composable
private fun ToDoRow(task: Task, vm: SomeViewModel) {
Row(modifier = Modifier.fillMaxWidth().clickable { vm.toggleState(task) }) {
Text(text = task.name, color = if (!task.isCompleted) Color.Red else Color.Green)
Text(text = task.date.toString(), color = if (!task.isCompleted) Color.Red else Color.Green)
}
}
Я думал, это потому, что MutableStateFlow генерирует только изменения состояния, в данном случае моего списка дел. Несмотря на то, что toggleState меняет элемент в задаче, сама моя ссылка на задачу не меняется.
Поэтому я переписал toggleState

Код: Выделить всё

    fun toggleState(task: Task) {
val updatedTask = task.copy(isCompleted = !task.isCompleted)
val indexOf = todo.indexOfFirst { it.name == task.name }
todo[indexOf] = updatedTask
val list = mutableListOf()
list.addAll(todo)
_tasks.value = list
}
Теперь _tasks обновляется новой ссылкой, и я ожидаю, что это будет замечено моим компонуемым объектом MainContent. Но это не так, поскольку задачи снова не распространяют изменение состояния. Я хочу понять механизм, который StateFlow использует для определения изменения состояния. Я не понимаю, почему так сложно обновить состояние с помощью StateFlow.

Подробнее здесь: https://stackoverflow.com/questions/791 ... xplanation
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»