Мое приложение To-Do использует Room для хранения данных. Имеет два фрагмента: список задач и детали задачи (добавление и редактирование задачи). Проблема в том, что когда я обновляю поле Task * isFavourite
в TaskDetailsFragment, список в предыдущем фрагменте не обновляется (отображается старое значение isFavourite
). Я использовал двустороннюю привязку данных для соединения LiveData и представления. Все остальные поля (title
, description
, isCompleted
) корректно обновляются после редактирования, только isFavourite
CheckBox создает проблемы. Иногда значение обновляется правильно, когда я прокручиваю до конца списка (обновленный элемент не отображается) или когда я перезагружаю свое приложение. Более того, при обновлении значения isFavourite
непосредственно из представления списка поведение CheckBox корректно. Проблематично только обновить его из другого фрагмента.
RecyclerViewAdapter:
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
val task = tasks[position]
holder.taskCheckBox.apply {
setOnCheckedChangeListener { _, isChecked ->
Timber.i(isChecked.toString())
taskViewClickListener.onCheckBoxClick(position, task, isChecked)
}
isChecked = task.isCompleted
setTintListByColor(task.priority.color)
}
holder.taskTitleTextView.apply {
text = task.title
setOnClickListener {
taskViewClickListener.onTaskClick(position, task)
}
}
holder.isTaskFavouriteCheckBox.apply {
setOnCheckedChangeListener { _, isChecked ->
taskViewClickListener.onFavouriteClick(position, task, isChecked)
}
isChecked = task.isFavourite
}
}
fun updateTasksList(newTasks: List<Task>) {
val callback = TaskDiffCallback(tasks, newTasks)
val result = DiffUtil.calculateDiff(callback)
tasks.apply {
clear()
addAll(newTasks)
}
result.dispatchUpdatesTo(this)
}
TaskDao:
@Query("SELECT * FROM tasks WHERE is_completed = 0 ORDER BY creation_date DESC")
fun getAllOrderedByCreationDate(): Flow<List<Task>>
@Update
suspend fun update(task: Task)
TaskRepository:
fun getAll(): Flow<List<Task>> {
return taskDao.getAllOrderedByCreationDate()
}
TaskViewModel:
var tasks: LiveData<List<Task>> = taskRepository.getAll().asLiveData()
TasksFragment:
viewModel.tasks.observe(this) {
recyclerViewAdapter.updateTasksList(it)
}
TaskDetailsViewModel:
fun saveTask(inEditMode: Boolean) {
val success = updateTaskDetails()
if (success) {
if (inEditMode)
updateTask(task)
else
insertTask(task)
scheduleReminder()
_taskSaved.call()
}
}
private fun updateTaskDetails(): Boolean {
val title = taskTitle.value
val description = taskDescription.value
val priority = taskPriority.value
val isFavourite = isTaskFavourite.value
val isCompleted = isTaskCompleted.value
if (title.isNullOrBlank()) {
_taskError.value = "Task title cannot be empty"
return false
}
if (priority == null) {
_taskError.value = "Task priority cannot be empty"
return false
}
if (isFavourite == null)
return false
if (isCompleted == null)
return false
with(task) {
this.title = title
this.description = description
this.priority = priority
this.isFavourite = isFavourite
this.isCompleted = isCompleted
}
return true
}
fun updateTask(task: Task) {
viewModelScope.launch(Dispatchers.IO) {
taskRepository.update(task)
}
}