Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is lifecycle for RecyclerView adapter?

I'm requesting images from presenter in adapter:

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

I should unsubscribe when ViewHolder is re-used. It is easy.

But how stop all subscription when view is destroyed? I should also probably nullify presenter reference to avoid memory leak

like image 986
Eugen Martynov Avatar asked Jun 07 '16 08:06

Eugen Martynov


People also ask

What does RecyclerView adapter do?

RecyclerView. Adapter base class for presenting List data in a RecyclerView , including computing diffs between Lists on a background thread. Adapters provide a binding from an app-specific data set to views that are displayed within a RecyclerView .

How many times onCreateViewHolder called?

By default it have 5.

How many times onBindViewHolder is called?

1 Answer. Show activity on this post. Yes it is perfectly normal for a RecyclerView to call onBindViewHolder() multiple times. A RecyclerView only creates minimum number of Views needed to fill the screen.

What is the difference between list adapter and RecyclerView adapter?

Required ViewHolder in Adapters - ListView adapters do not require the use of the ViewHolder pattern to improve performance. In contrast, implementing an adapter for RecyclerView requires the use of the ViewHolder pattern for which it uses RecyclerView. Viewholder .


1 Answers

I think the best way to do that would be to:

  1. Keep a subscription reference in the SiteAdapter.ViewHolder
  2. unsubscribe the subscription object in onBindViewHolder (it's called when the ViewHolder is reused)
  3. Keep the CompositeSubscription object in your adapter
  4. Use the onDetachedFromRecyclerView method of your Adapter to unsubscribe the compositeSubscription

Like so:

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         }     } } 
like image 100
Bartek Lipinski Avatar answered Oct 07 '22 02:10

Bartek Lipinski