1

Modifié:Anonyme Listener à RecyclerView Adaptateur

Je veux savoir sur la création Anonyme Listener dans bindViewHolder méthode pose aucun problème de performance ou non pour un grand ensemble de données.

Supposons que je possède un adaptateur RecyclerView. Et dans bindViewHolder méthode si je mets tous mes auditeurs Anonymement cela cause-t-il un problème de performance? Parce que lorsque l'utilisateur fait défiler le RecyclerView, il va créer beaucoup d'écouteurs anonymes et les définir sur les vues.

Exemple:

view.setOnClickListener(new View.OnClickListener() 
{ 
    @Override 
    public void onClick(View v) 
    { 
    } 
}); 

Ou je peux OnClickListener implémente dans ma classe de ViewHolder et ajoutez juste views.Like

view.setOnClickListener(this); 

ici beaucoup d'auditeurs anonymes ne sont pas créés. Est-ce que cela fonctionne mieux avec le calcul de performance précédent pour un grand ensemble de données?

Merci d'avance.

+0

Peut-on essayer ceci dans le viewholder create listener et il y a une propriété this.setIsRecyclable (false) qui va améliorer les performances peut essayer celui-ci https://stackoverflow.com/questions/46095866/getting-android-recyclerview-to -update-view-inside-réaction-native-component/46313257 # 46313257 –

Répondre

0

Fondamentalement, vous définissez un OnClickListener dans chaque article de votre RecyclerView et de le "connecter" à votre Activity ou Fragment. Cette "connexion" est importante, donc vous pouvez avoir votre onItemClick méthode à l'intérieur de votre Activity ou Fragment et accéder aux membres là-bas.

Une implémentation minimale ressemblerait à ceci (dans un Fragment, mais vous pouvez également utiliser un Activity):

public class YourFragment extends Fragment implements RecyclerViewAdapter.ItemClickListener { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
     super.onCreateView(inflater, container, savedInstanceState); 

     View view = inflater.inflate(R.layout.fragment_your, container, false); 

     RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview); 
     RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(activity); 
     recyclerViewAdapter.setClickListener(this); 
     recyclerView.setAdapter(recyclerViewAdapter); 

     return view; 
    } 

    @Override 
    public void onItemClick(View view, int position) { 
     // do something here 
    } 
} 

Et la classe Adapter

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { 
    private ItemClickListener itemClickListener; 

    void setClickListener(ItemClickListener itemClickListener) { 
     this.itemClickListener = itemClickListener; 
    } 

    interface ItemClickListener { 
    void onItemClick(View view, int position); 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
     // TextView is an example 
     final TextView textView; 

     ViewHolder(View itemView) { 
      super(itemView); 
      textView = (TextView) itemView.findViewById(R.id.text); 
      textView.setOnClickListener(this); 
     } 

     @Override 
     public void onClick(View view) { 
      if (itemClickListener != null) { 
       itemClickListener.onItemClick(view, getAdapterPosition()); 
      } 
     } 
    } 
} 
+0

Je ne demande pas ici la solution, je veux juste savoir si cela cause un problème de performance. En tout cas merci. –

1

RecyclerView affichera seulement quelques articles, ViewHolder ne sera créé que pour les éléments visibles, donc même si vous avez des milliers d'éléments dans votre adaptateur, seule une petite fraction de ViewHolders est créée.

Mais vous devez être prudent avec addListener méthodes, pour la plupart des setListener méthodes, vous serez même réglage d'écoute encore et encore quand l'élément est recyclé, qui ne prend pas moins de quelques millisecondes car il ne garde que référence de l'auditeur la mise en oeuvre.

Mais avec addListener, vous devrez supprimer old listener avant d'en ajouter un nouveau.

Exemple de setListener est setClickListener et exemple de addListener est addTextWatcher

//.. part of adapter 

private TextWatcher textWatcher; 

public void bindViewHolder(DataViewHolder holder, int index){ 

    // no performance issue 
    holder.button.setClickListener(....); 

    // wrong, this is added everytime 
    holder.editText.addTextWatcher(....); 


    // this is safe... 
    if(textWatcher != null) 
     holder.editText.removeTextWatcher(textWatcher); 

    textWatcher = new TextWatcher(){ 
     // ... implementation 
    }; 
    holder.editText.addTextWatcher(textWatcher); 
} 
+1

Merci pour votre réponse. En fait, je me suis concentrée sur le réglage anonyme des auditeurs (j'ai édité ma question désolé pour cela). Je pense que chaque fois que je mets des listeners anonymes dans la méthode 'bindViewHolder' je vais créer une nouvelle classe anonyme. lors du défilement. Corrigez-moi si je me trompe. Merci –

0

Je suis sûr que le compilateur crée juste une version concrète sans nom de votre classe anonyme sous le capot. C'est presque identique à l'implémentation de l'interface et en fournissant this comme un écouteur concret. De manière réaliste, vous ne devriez pas avoir de problème de performance avec l'un ou l'autre.Gardez simplement à l'esprit le fait qu'une classe anonyme contient une référence à la classe externe. Cela peut créer des fuites de mémoire (exemple: si la classe externe est une activité) ou simplement faire en sorte que la collecte des ordures se fasse en même temps au lieu de petites pièces au fil du temps. Voir Implicit and Synthetic Parameters dans la documentation Oracle pour plus de détails à ce sujet.