Issue
I have a RecyclerView with an adapter that uses AssyncListDiffer. The problem I have is that the recyclerview is not updated when changes happen in the LiveData. The observer is notified but the list doesn't update.
class HourAdapter(private val interaction: HourInteraction? = null) :
RecyclerView.Adapter<HourAdapter.HourViewHolder>() {
private val differ = AsyncListDiffer(this, DIFF_CALLBACK)
fun submitList(list: List<Hour>?) {
differ.submitList(list)
}
private fun getHourAt(position: Int): Hour {
return differ.currentList[position]
}
override fun getItemCount(): Int {
return differ.currentList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HourViewHolder {...}
override fun onBindViewHolder(holder: HourViewHolder, position: Int) {...}
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Hour>() {
override fun areItemsTheSame(oldItem: Hour, newItem: Hour): Boolean {
return (oldItem.name == newItem.name) && (oldItem.isChecked == newItem.isChecked)
}
override fun areContentsTheSame(oldItem: Hour, newItem: Hour): Boolean {
return oldItem == newItem
}
}
class HourViewHolder
(
internal val binder: HourItemBinding
) : RecyclerView.ViewHolder(binder.root)
}
I use the "submitList()" to submit the new list. But it doesn't work.
I looked for solutions online and basically there were 2 options:
In the submitList function, call the "submitList" of AssyncListDiffer twice like this:
differ.submitList(null) differ.submitList(list) }```
- The second option was to use ListAdapter and override the "submitList" function like this:
override fun submitList(list: List<Hour>?) {
super.submitList(list?.let { ArrayList(it) })
}
The first solution works, but the recyclerview blinks whenever I update it. The second solution to override the method does not work for me.
I've been trying to fix this for days, but I can't make it work. Also, I don't want to use notifyItemChanged() or notifyDataSetChanged().
Is there another way?
Solution
I came around the same thing and observed the following.
Each time AsyncListDiffer
received my list; it was the same object as previously - present in memory. Hence, the differ decided nothing changed and did not submit the updated list.
My list contained one object inside, and for each submission attempt I was changing one field. The object and the list of course remained the same.
So, I wondered why option number 2 did not work, and turned out that I needed to be a little more expressive:
submitList(it.map {
it.copy()
})
Otherwise, Kotlin would not make a deep copy of the object.
Answered By - pratclot
Answer Checked By - Mildred Charles (JavaFixing Admin)