android - notifyitemremoved - recyclerview hermosa programacion
¿Qué es el ciclo de vida del adaptador RecyclerView? (2)
Creo que la mejor manera de hacerlo sería:
- Mantenga una referencia de
subscription
en elSiteAdapter.ViewHolder
-
unsubscribe
lasubscription
objeto desubscription
enonBindViewHolder
(se llama cuando se reutilizaViewHolder
) - Mantenga el objeto
CompositeSubscription
en suadapter
- Utilice el método
onDetachedFromRecyclerView
de suAdapter
paraunsubscribe
launsubscribe
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.