Мне кажется, что вы допустили две ошибки одновременно.
Первая (не уверен, что это ошибка, но обычно она совершается противоположным образом): вы вернуть false
из метода areContentsTheSame
. Это заставляет RecyclerView
повторно привязать видоискатель. Это не так, если изменился только порядок элемента, возвращайте false
, только если вам нужно повторно привязать видоискатель. Поэтому, если содержимое элементов не изменяется, по умолчанию возвращается true
.
Второй подозреваемый - ваш setChar
метод. Кажется, что DiffCallback
принимает два одинаковых списка все время. Если у вас есть список данных в активности / фрагменте и вы передаете тот же List
для установки новых данных, то это заставляет DiffCallback
работать некорректно, поскольку DiffCallback
не видит никаких изменений позиции в ваших списках как они оба равны.
Я только что проверил, и только комбинация этих двух дает результат, который у вас есть. Итак, что вы должны сделать:
class YourAdapter(..., charList: List<Char>, ...): RecyclerView.Adapter<...>() {
private val mChars = ArrayList(charList)
// You have to keep a different List object (so, a copy) of the one you pass from the activity
...
fun setChar(list: List<Char>) {
val diffResult = DiffUtil.calculateDiff(CharDiffCallBack(mChars, list), true)
mChars.clear()
mChars.addAll(list)
diffResult.dispatchUpdatesTo(this)
}
}
class CharDiffCallBack(private val mOldList: List<Char>, private val mNewList: List<Char>) :
DiffUtil.Callback() {
...
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = true
}
Таким образом DiffCallback
всегда берет два разных списка, один старый и один с обновленными данными. Также верните true
из areContentsTheSame
method