studio llenar elementos ejemplo dinamico agregar android kotlin listadapter

android - llenar - ListAdapter no actualiza el elemento en reyclerview



listview dinamico android studio (2)

Estoy usando la nueva biblioteca de soporte ListAdapter . Aquí está mi código para el adaptador

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) } } }

Estoy actualizando el adaptador con

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

Mi clase de diferencia

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 } }

Lo que sucede es cuando se llama a submitList la primera vez que el adaptador procesa todos los elementos, pero cuando se vuelve a llamar a submitList con propiedades de objeto actualizadas, no vuelve a representar la vista que ha cambiado.

Vuelve a representar la vista a medida que me desplazo por la lista, que a su vez llama a bindView()

Además, he notado que al llamar a adapter.notifyDatasSetChanged() después de enviar la lista, se presenta la vista con los valores actualizados, pero no quiero llamar a notifyDataSetChanged() porque el adaptador de lista tiene diferentes utilidades incorporadas

¿Puede alguien ayudarme aquí?


Edit: entiendo por qué sucede esto que no era mi punto. Mi punto es que al menos debe dar una advertencia o llamar a la función notifyDataSetChanged() . Porque aparentemente estoy llamando a la función submitList(...) por una razón. Estoy bastante seguro de que la gente está tratando de averiguar qué salió mal durante horas hasta que descubren que submitList () ignora silenciosamente la llamada.

Esto se debe a la lógica extraña de Google . Por lo tanto, si pasa la misma lista al adaptador, ni siquiera llama al DiffUtil .

public void submitList(final List<T> newList) { if (newList == mList) { // nothing to do return; } .... }

Realmente no entiendo todo el punto de este ListAdapter si no puede manejar los cambios en la misma lista. Si desea cambiar los elementos de la lista, pase al ListAdapter y vea los cambios, entonces necesita crear una copia en profundidad de la lista o usar RecyclerView normal con su propia clase DiffUtill .


La biblioteca asume que está utilizando Room o cualquier otro ORM que ofrezca una nueva lista asíncrona cada vez que se actualice, así que solo llamar a submitList funcionará, y para los desarrolladores descuidados, evita hacer los cálculos dos veces si se llama a la misma lista.

La respuesta aceptada es correcta, ofrece la explicación pero no la solución.

Lo que puede hacer en caso de que no esté utilizando ninguna de estas bibliotecas es:

submitList(null); submitList(myList);

Otra solución sería anular submitList (que no causa ese parpadeo rápido) como tal:

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

Un poco retrasado en la lógica pero funciona perfectamente. Mi método preferido es el segundo porque no causa que cada fila reciba una llamada onBind.