web-dev-qa-db-fra.com

Où dois-je désassocier ButterKnife 8.x.x dans un ViewHolder?

J'ai une classe RecycleView.ViewHolder qui utilise des annotations ButterKnife.

Mon code doit-il être non lié dans cette classe ViewHolder également?

public class AView extends RecyclerView.ViewHolder
{
    @BindView(R.id.a_text_view) TextView aText;

    public AView(final View view)
    {
        super(view);
        ButterKnife.bind(this, view); // It returns an Unbinder, but where should I call its unbind()?
    }
}

Les documents ( http://jakewharton.github.io/butterknife/ ) ne parlent pas de cette question.

22
Balázs Árva

Selon Jake Wharton, auteur de Butterknife, unbind() n’est requis que pour Fragments. Voir ce commentaire sur le suivi des problèmes:

https://github.com/JakeWharton/butterknife/issues/879

Q: Dans la RecyclerView, comment dissocions-nous la ViewHolder?

A: Tu n'as pas besoin. Seul Fragments doit entrer dans onDestroyView().

La raison étant que 

[ViewHolders] ne survivez pas à la vue associée. Un Fragment fait.

En d'autres termes, étant donné qu'une Fragment peut continuer d'exister après la destruction de sa Views, vous devez appeler .unbind() depuis une Fragment pour libérer la référence à la Views (et autoriser la récupération de la mémoire associée).

Avec ViewHolder, le cycle de vie du détenteur est identique à celui de la Views qu’il détient. En d'autres termes, les variables ViewHolder et Views sont détruites en même temps; il n'y a donc jamais de référence persistante que vous devez effacer manuellement.

40
Tim Malseed

Voici une explication de QUAND et POURQUOI utiliser la méthode unbind():

Reliure Réinitialiser

Les fragments ont un cycle de vie de vue différent des activités. Quand lier un fragment dans onCreateView, définissez les vues sur null dans onDestroyView. Butter Knife retourne une instance Unbinder lorsque vous appelez bind pour le faire pour vous. Appelez sa méthode unbind dans le fichier rappel du cycle de vie approprié.

public class FancyFragment extends Fragment {
  @BindView(R.id.button1) Button button1;
  @BindView(R.id.button2) Button button2;
  private Unbinder unbinder;

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    unbinder = ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }

  @Override public void onDestroyView() {
    super.onDestroyView();
    unbinder.unbind();
  }
}

De: http://jakewharton.github.io/butterknife/#reset

vous n'avez donc pas besoin de unbind d'aucune vue de ViewHolder.

J'espère que ça va aider

10
piotrek1543

Il y a un exemple dans la doc, qui montre comment utiliser cette bibliothèque dans le ViewHolder:

static class ViewHolder {
    @BindView(R.id.title) TextView name;
    @BindView(R.id.job_title) TextView jobTitle;

    public ViewHolder(View view) {
      ButterKnife.bind(this, view);
    }
  }

Ainsi, il n'est pas nécessaire d'appeler unbind pour votre ViewHolder.

3
Anton K

Oui, ils le font . Ceci n'est nécessaire que pour les fragments.

2
R. Zagórski

Il suffit de l'utiliser:

@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
    if (unbinder != null) {
        unbinder.unbind();
    }
}
0
AndroSco