Как обновлять список задач из Room через Kotlin Flow

Как обновлять список задач из Room через Kotlin Flow
Содержание статьи

Если экран Android должен обновляться после записи в локальную базу, верните Flow<List<Task>> из метода Room DAO. Запись можно выполнить отдельной suspend-функцией. На Mentoring.digital покажем это на списке незавершённых задач.

Опишите наблюдаемый запрос и изменение

Пример рассчитан на существующую базу Room с сущностью Task, таблицей tasks и полями id и done. Чтение возвращает все незавершённые задачи в порядке ID, а запись меняет флаг одной задачи.

import androidx.room.Dao
import androidx.room.Query
import kotlinx.coroutines.flow.Flow

@Dao
interface TaskDao {
    @Query("SELECT * FROM tasks WHERE done = 0 ORDER BY id")
    fun observeOpen(): Flow<List<Task>>

    @Query("UPDATE tasks SET done = :done WHERE id = :id")
    suspend fun setDone(id: Long, done: Boolean)
}

После изменения наблюдаемой таблицы Room может выполнить запрос повторно, даже если изменённая строка не входила в выборку. Чтобы экран получал только отличающиеся списки, примените distinctUntilChanged(). Сравнение использует равенство значений списка. Для элементов подходят неизменяемые модели с равенством по полям.

Подключите поток к экрану Compose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.Flow

@Composable
fun TaskRoute(openTasks: Flow<List<Task>>) {
    val tasks by openTasks.collectAsStateWithLifecycle(
        initialValue = emptyList()
    )
    TaskList(tasks)
}

Передайте в экран стабильный поток из слоя данных или ViewModel. Здесь TaskList обозначает ваш компонент списка. Начальное пустое значение подходит учебному примеру. Если интерфейс должен различать загрузку и действительно пустую базу, предусмотрите отдельное состояние загрузки.

Проверьте изменение и неизменный результат

Подпишитесь на список и отметьте открытую задачу выполненной. Она должна исчезнуть из следующего результата. Затем обновите уже скрытую задачу без изменения открытых строк. Проверьте, что после distinctUntilChanged() прежний список не поступает повторно. Для теста используйте отдельную базу с фиксированными данными.

Подписку и хранение состояния можно отработать на курсе Android-разработки или разобрать вместе с наставником по Kotlin.

Похожие статьи по данной теме