我正在写一个Todo应用程序的Android使用Jetpack组成和房间作为数据库解决方案。对于每个待办事项/任务,我有一些数据需要持久化在数据库中(例如:文本、到期日、...)和一些仅UI(例如,如果任务当前已展开,则显示更多详细信息)。
数据库/仓库为我提供了Task
列表流:
@Entity(tableName="task")
data class Task(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val text: String,
val dueDate: LocalDate,
)
@Dao
interface TaskDao {
// ...other methods
@Query("SELECT * FROM task") fun getAllTasks(): Flow<List<Task>>
}
class TaskRepository(private val taskDao: TaskDao) {
// ...other methods
override fun getAllTasks() = taskDao.getAllTasks()
}
为了在UI中显示任务,我有一个TaskUiState
类。我的屏幕级ViewModel目前公开了一个TaskUiState
列表流:
data class TaskUiState(
val id: Int,
val text: String,
val dueDate: LocalDate,
val expanded: Boolean = false,
)
class MainScreenViewModel(
private val taskRepository: TaskRepository,
) : ViewModel() {
val taskList: StateFlow<List<TaskUiState>> =
taskRepository
.getAllTasks()
.map { tasks -> tasks.map { TaskUiState(it.id, it.text, it.dueDate) } }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = emptyList()
)
}
我现在的问题是,我不能更改任务是否展开,因为我不知道如何正确地存储每个任务的信息并将其Map到数据库实体。
我以为这是一个常见的问题,但找不到任何关于它的信息。什么是一个好的和合理的性能的方式来做到这一点?我考虑过将Map<Int, Boolean>
从任务ID存储到isExpanded。然后在将Task
sMap到TaskUiState
s时使用此查找。我需要确保taskList
流在这个Map改变时更新,所以我可能需要使用StateFlow<Map<Int, Boolean>>
并使用flow combine
函数。这种方法是否可行?请注意,我并不是在为“扩展”状态寻找特定的解决方案(因为这只是一个最小的示例),而是在寻找一种更通用的方法,将DB持久化状态和仅UI状态结合起来。
1条答案
按热度按时间e4eetjau1#
理想情况下,使用
combine
是更好的方法,但只需使用Set
而不是Map