簡體   English   中英

RecyclerView ListAdapter 未正確更新列表

[英]RecyclerView ListAdapter does not update list correctly

我正在使用Android RoomRx Flowable更新RecyclerView將對象從我的數據庫中。 為了獲得更好的動畫和性能,我更新了項目以在我的項目中使用新的ListAdapter

問題是當用戶按下Checkbox ,Task 對象更新為完成,數據庫會反映此更改,但有時適配器ListAdapter會通知我的onBindViewHolder ,有時它會說我的視圖已更新。

任務列表片段

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

任務道

@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
}

任務

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
}

DiffUtil

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
}

調試應用程序,有時isCompleted字段正確更新,有時該字段已在 Diff 期間更新,因此它表示視圖沒有更新。 我找不到這個問題的任何模式。 就我而言,有時視圖holder.viewStrike更改其可見性,有時會保持不一致狀態。

該問題似乎與ListAdapter本身有關,它有時會發送帶有更新值的oldItem ,因此沒有要更新的差異。

我錯過了任何實現嗎?

可能會遲到,但我會為其他人寫一個答案。 您不應該以這種方式使用 areContentsTheSame。 您必須比較與這兩個可以更改的對象相關的值。 喜歡:

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

但是比較永遠不會改變的值是沒有必要的,比如:id

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM