ListAdapter не обновляет элемент в reyclerview

Я использую новую библиотеку поддержки ListAdapter. Вот мой код для адаптера

class ArtistsAdapter : ListAdapter<Artist, ArtistsAdapter.ViewHolder>(ArtistsDiff()) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(parent.inflate(R.layout.item_artist))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(getItem(position))
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        fun bind(artist: Artist) {
            itemView.artistDetails.text = artist.artistAlbums
                    .plus(" Albums")
                    .plus(" u2022 ")
                    .plus(artist.artistTracks)
                    .plus(" Tracks")
            itemView.artistName.text = artist.artistCover
            itemView.artistCoverImage.loadURL(artist.artistCover)
        }
    }
}

Я обновляю адаптер с

musicViewModel.getAllArtists().observe(this, Observer {
            it?.let {
                artistAdapter.submitList(it)
            }
        })

мой класс diff

class ArtistsDiff : DiffUtil.ItemCallback<Artist>() {
    override fun areItemsTheSame(oldItem: Artist?, newItem: Artist?): Boolean {
        return oldItem?.artistId == newItem?.artistId
    }

    override fun areContentsTheSame(oldItem: Artist?, newItem: Artist?): Boolean {
        return oldItem == newItem
    }
}

что происходит, когда submitList вызывается в первый раз, когда адаптер отображает все элементы, но когда submitList вызывается снова с обновленными свойствами объекта, он не повторно отображает измененное представление.

он повторно отображает представление при прокрутке списка, который в Очередь вызовов bindView()

кроме того, я заметил, что вызов adapter.notifyDatasSetChanged() после отправки списка отображает представление с обновленными значениями, но я не хочу вызывать notifyDataSetChanged() потому что список адаптер имеет diff utils встроенный

может кто-нибудь помочь мне здесь?

2 ответов


Edit: я понимаю, почему это происходит, что не было моей точкой зрения. Я имею в виду, что он, по крайней мере, должен дать предупреждение или вызвать


библиотека предполагает, что вы используете Room или любой другой ORM, который предлагает новый асинхронный список каждый раз, когда он обновляется, поэтому просто вызов submitList на нем будет работать, а для небрежных разработчиков он предотвращает выполнение вычислений дважды, если вызывается тот же список.

принятый ответ правильный, он предлагает объяснение, но не решение.

что вы можете сделать, если вы не используете такие библиотеки:

submitList(null);
submitList(myList);

другое решение было бы переопределите submitList (который не вызывает этого быстрого мигания) как таковой:

@Override
public void submitList(final List<Author> list) {
    super.submitList(list != null ? new ArrayList<>(list) : null);
}

своего рода отсталая логика, но работает отлично. Мой предпочтительный метод-второй, потому что он не заставляет каждую строку получать вызов onBind.