AsyncListDiffer не обновляет recyclerview
У меня есть RecyclerView с адаптером, который использует AssyncListDiffer. У меня проблема в том, что recyclerview не обновляется, когда происходят изменения в LiveData. Наблюдатель получает уведомление, но список не обновляется.
Это мой адаптер:
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)
}
Я используюsubmitList(), чтобы отправить новый список. Но не работает.
Я искал решения в Интернете и в основном было 2 варианта:
В submitList функции, называют "submitList" из AssyncListDiffer дважды, как это:
differ.submitList(null) differ.submitList(list) }```
- Второй вариант - использовать ListAdapter и переопределить функцию submitList следующим образом:
override fun submitList(list: List<Hour>?) {
super.submitList(list?.let { ArrayList(it) })
}
Первое решение работает, но каждый раз, когда я обновляю его, программа recyclerview мигает. Второе решение по переопределению метода мне не подходит.
Я пытался исправить это несколько дней, но не могу заставить его работать. Кроме того, я не хочу использовать notifyItemChanged() или notifyDataSetChanged().
Есть другой способ?
3 ответа
Я пришел к тому же самому и заметил следующее.
Каждый раз AsyncListDiffer
получил мой список; это был тот же объект, что и раньше - присутствующий в памяти. Следовательно, дифферент решил, что ничего не изменилось, и не представил обновленный список.
В моем списке был один объект, и для каждой попытки отправки я менял одно поле. Объект и список, конечно же, остались прежними.
Итак, я задумался, почему вариант номер 2 не сработал, и оказалось, что мне нужно было быть немного более выразительным:
submitList(it.map {
it.copy()
})
В противном случае Котлин не сделал бы глубокую копию объекта.
Иди по этому пути
fun submitList(list: MutableList<FollowingUserProfile>) {
val x = mutableListOf<FollowingUserProfile>().apply{
addAll(list)
}
differ.submitList(x)
}
Я пытался удалить строку и имел ту же проблему, но решил ее следующим образом:
Код ниже добавлен во фрагмент:
private void deleteRow(int position) {
ArrayList<Card> cardsArrayList = adapter.getArrayList();
cardsArrayList.remove(position);
adapter.submitList(cardsArrayList);
}
И этот код находится в адаптере:
public ArrayList<Card> getArrayList(){
List<Card> cardList = mDiffer.getCurrentList();
return new ArrayList<>(cardList) ;
}