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 варианта:

  1. В submitList функции, называют "submitList" из AssyncListDiffer дважды, как это:

        differ.submitList(null)
        differ.submitList(list)
    }```
    
  2. Второй вариант - использовать 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) ;
    }
Другие вопросы по тегам