2016-06-07 28 views
26

mam zainteresowanie obrazy z prezenterem w adapterze:Co to jest cykl życia adaptera RecyclerView?

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

powinienem zrezygnować, gdy ponownie wykorzystywane ViewHolder. To jest łatwe.

Ale jak zatrzymać wszystkie subskrypcje, gdy widok jest zniszczony? Powinienem też prawdopodobnie unieważnić odniesienie prezentera aby uniknąć pamięć przeciekać

+8

proszę wyjaśnić dlaczego downvoting –

Odpowiedz

11

Myślę, że najlepszym sposobem na to byłoby:

  1. Zachowaj subscription odniesienie w SiteAdapter.ViewHolder
  2. unsubscribe obiektu subscription w onBindViewHolder (to się nazywa po ViewHolder jest wykorzystywany)
  3. przechowywać obiekt CompositeSubscription w swoim adapter
  4. Zastosowanie metody onDetachedFromRecyclerView z Twojego Adapter do unsubscribecompositeSubscription

tak:

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

Cool, więc nie ma metody na adapterze, który nazywa się 'RecyclerView' gdy jest odłączony z działalności –

+0

Cóż ... faktycznie jest jeden - "onDetachedFromRecyclerView" i może to łatwo zrobić to, co obecnie robi 'recycle(). Dobry pomysł :) –

+0

Pozwól mi zaktualizować odpowiedź wtedy. :) –