RecyclerView ListAdapter无法正确更新列表

时间:2018-11-27 16:19:58

标签: android android-recyclerview rx-java android-adapter android-room

我正在使用Android RoomRx Flowable更新RecyclerView,将对象从我的数据库中移除。为了获得更好的动画效果和性能,我将项目更新为在项目中使用新的ListAdapter

问题是,当用户按下Checkbox任务对象已完成更新时,数据库反映了此更改,但是有时适配器ListAdapter会通知我的{{1 }},有时它说我的视图已经更新。

TaskListFragment

onBindViewHolder

TaskDao

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    viewModel.loadTasks(onTasksLoaded = { adapter.submitList(it) })
}

TaskListAdapter

@Query("SELECT * FROM task")
fun getAllTasks(): Flowable<MutableList<Task>>

任务

class TaskListAdapter : ListAdapter<Task, BindingHolder<*>>(TaskDiffCallback()) {

    override fun onBindViewHolder(holder: BindingHolder<*>, position: Int) {
        val task = getItem(position)
        // more binding code

        // THE ISSUE IS HERE
        if (task.completed) {
            holder.viewStrike.visibility = View.VISIBLE
        } else {
            holder.viewStrike.visibility = View.INVISIBLE
        }
    }

    // more adapter code
}

DiffUtil

data class Task(
    @ColumnInfo(name = "task_is_completed") var completed: Boolean = false,
    @ColumnInfo(name = "task_description") var description: String,
    @ColumnInfo(name = "task_category_id") var categoryId: Long? = null,
    @ColumnInfo(name = "task_due_date") var dueDate: Calendar? = null
) : Parcelable {

    @IgnoredOnParcel
    @ColumnInfo(name = "task_id")
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0
}

调试应用,有时 class TaskDiffCallback : DiffUtil.ItemCallback<Task>() { override fun areItemsTheSame(oldItem: Task, newItem: Task) = oldItem.id == newItem.id override fun areContentsTheSame(oldItem: Task, newItem: Task) = oldItem.task == newItem.task } 字段正确更新,并且有时字段在Diff期间已经更新,因此它表示视图没有更新。我找不到此问题的任何模式。就我而言,视图isCompleted有时会更改其可见性,有时会保持不一致状态。

问题似乎与holder.viewStrike本身有关,有时会向ListAdapter发送更新后的值,因此没有要更新的差异。

我错过任何实现了吗?

1 个答案:

答案 0 :(得分:0)

可能已经晚了,但我会为其他人写一个答案。 您不应以这种方式使用areContentsTheSame。 您必须比较与可以更改的这两个对象相关的值。 喜欢:

 override fun areContentsTheSame(oldItem: Task, newItem: Task){
  return if(oldItem.completed == newItem.completed && oldItem.description == newItem.description && oldItem.dueDate == newItem.dueDate)}

但是不必比较永远不变的值,例如:id