sethasstableids recyclerview programacion notifyitemremoved hermosa getitemviewtype getitemcount dependency android android-recyclerview android-lifecycle

android - notifyitemremoved - recyclerview hermosa programacion



¿Qué es el ciclo de vida del adaptador RecyclerView? (2)

Creo que la mejor manera de hacerlo sería:

  1. Mantenga una referencia de subscription en el SiteAdapter.ViewHolder
  2. unsubscribe la subscription objeto de subscription en onBindViewHolder (se llama cuando se reutiliza ViewHolder )
  3. Mantenga el objeto CompositeSubscription en su adapter
  4. Utilice el método onDetachedFromRecyclerView de su Adapter para unsubscribe la unsubscribe compositeSubscription

Al igual que:

public class SiteAdapter extends RecyclerView.Adapter<SiteAdapter.ViewHolder> { private CompositeSubscription compositeSubscription = new CompositeSubscription(); // other needed SiteAdapter methods @Override public void onBindViewHolder(SiteAdapter.ViewHolder holder, int position) { if (holder.subscription != null && !holder.subscription.isUnsubscribed()) { compositeSubscription.remove(holder.subscription); // this will unsubscribe the subscription as well } Site site = sites.get(position); holder.siteName.setText(site.getName()); requestHolderLogo(holder, site.getLinks().getLogoUrl()); } private void requestHolderLogo(final SiteAdapter.ViewHolder holder, final String logoUrl) { holder.subscription = presenter.bitmap(logoUrl) .subscribe( bitmap -> { holder.siteLogo.setImageBitmap(bitmap); holder.siteLogo.setVisibility(View.VISIBLE); }, error -> { holder.siteName.setVisibility(View.VISIBLE); }); compositeSubscription.add(holder.subscription); } @Override public void onDetachedFromRecyclerView(RecyclerView recyclerView) { compositeSubscription.unsubscribe(); } public static class ViewHolder extends RecyclerView.ViewHolder { public Subscription subscription; // some holder-related stuff public ViewHolder(View itemView) { super(itemView); // init holder } } }

Estoy solicitando imágenes del presentador en el adaptador:

@Override public void onBindViewHolder(SiteAdapter.ViewHolder holder, int position) { Site site = sites.get(position); holder.siteName.setText(site.getName()); requestHolderLogo(holder, site.getLinks().getLogoUrl()); } private void requestHolderLogo(final ViewHolder holder, final String logoUrl) { compositeSubscription.add( presenter.bitmap(logoUrl) .subscribe( bitmap -> { holder.siteLogo.setImageBitmap(bitmap); holder.siteLogo.setVisibility(View.VISIBLE); }, error -> { holder.siteName.setVisibility(View.VISIBLE); }) ); }

Debería cancelar mi suscripción cuando se vuelva a utilizar ViewHolder . Es fácil.

Pero, ¿cómo detener todas las suscripciones cuando se destruye la vista? Probablemente también debería anular la referencia del presentador para evitar la pérdida de memoria


Para otros que tienen el mismo problema: viewDetachedFromWindow en el adaptador solo se invoca cuando el adaptador se establece en nulo en onPause (Actividad, Fragmento) u onDetachFromWindow (Actividad, Fragmento)

recyclerview.setAdapter (null)

Luego obtienes viewDetachedFromWindow (...) donde puedes liberar tus estados y suscripciones internas. Configuraría tus suscripciones en bind, asegúrate de que antes de cada invocación de enlace reenvases las suscripciones antiguas, ya que una vista puede reciclarse.

Otra posibilidad es inflar una vista personalizada en lugar de solo un diseño en su fábrica. Luego puede hacer la limpieza en la vista personalizada onDetachFromWindow (). También obtiene onDetachedFromWindow sin configurar el adaptador como nulo.