1

Edited:Anonymous Zuhörer in RecyclerView Adapter

ich wissen will über das Erstellen von Anonymous Listener in bindViewHolder Methode jedes Leistungsproblem verursachen oder nicht für große Datenmengen.

Angenommen, ich habe einen RecyclerView Adapter. Und in bindViewHolder Methode, wenn ich alle meine Zuhörer einstellen Anonym verursacht dies irgendein Leistungsproblem? Denn wenn der Benutzer die RecyclerView scrollt, erstellt er viele anonyme Listener und setzt sie auf die Ansichten.

Beispiel:

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

oder ich kann OnClickListener in meiner ViewHolder Klasse implementiert und fügen Sie einfach

view.setOnClickListener(this); 

hier viele Anonymous Hörer views.Like werden nicht erstellt. Ist die Performance für große Datasets in der Leistungsberechnung besser?

Vielen Dank im Voraus.

+0

Können Sie versuchen, diese innere Viewholder Create Listener und es gibt eine Eigenschaft this.setIsRecycable (false), die Leistung besser machen kann versuchen, diese https://stackoverflow.com/questions/46095866/getting-android-recyclerview-to -update-view-inside-react-native-component/46313257 # 46313257 –

Antwort

0

Grundsätzlich setzen Sie einen OnClickListener in jedem Element Ihres RecyclerView und "verbinden" Sie es mit Ihrem Activity oder Fragment. Diese "Verbindung" ist wichtig, so können Sie Ihre onItemClick Methode innerhalb Ihrer Activity oder Fragment haben und auf die Mitglieder dort zugreifen.

Eine minimale Implementierung würde wie folgt aussehen (in einem Fragment, aber Sie können auch eine Activity verwenden):

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

Und die Adapter Klasse

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

Ich frage nicht hier die Lösung, ich will nur wissen, verursacht dies irgendein Leistungsproblem. Trotzdem danke. –

1

RecyclerView werden nur wenige Artikel angezeigt werden, ViewHolder wird nur für Elemente erstellt, die sichtbar sind. Wenn also in Ihrem Adapter Tausende von Elementen vorhanden sind, wird nur ein kleiner Bruchteil von ViewHolders erstellt.

Aber Sie müssen mit addListener Methoden, vorsichtig sein, denn die meisten setListener Methoden, werden Sie gleichen Hörer immer wieder werden eingestellt wird, wenn Artikel zurückgeführt wird, die nicht weniger dauert dann wenige Millisekunden, da es nur Referenz des Hörers hält Implementierung.

Aber mit addListener müssen Sie alten Listener entfernen, bevor Sie einen neuen hinzufügen.

Beispiel setListener ist setClickListener und Beispiel für addListeneraddTextWatcher ist

//.. 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

Danke für Ihre Antwort. Eigentlich habe ich mich darauf konzentriert, Zuhörer anonym zu stellen (Ich habe meine Frage bearbeitet. Entschuldigung dafür.) Ich denke, jedes Mal, wenn ich anonyme Listener in der 'bindViewHolder' Methode setze, werde ich neue anonyme Klasse erstellen beim Scrollen. Korrigiere mich, wenn ich falsch liege. Vielen Dank –

0

Ich bin ziemlich sicher, der Compiler erzeugt nur eine No-Name-Beton-Version Ihrer anonymen Klasse unter der Haube. Das ist fast identisch mit der Implementierung der Schnittstelle und this als konkreter Listener bereitzustellen. Realistisch gesehen sollten Sie bei beiden kein Leistungsproblem haben.

Denken Sie nur daran, dass eine anonyme Klasse einen Verweis auf die äußere Klasse enthält. Das kann zu Speicherlecks führen (Beispiel: Wenn die äußere Klasse eine Aktivität ist) oder einfach so einrichten, dass die Garbage Collection auf einmal statt kleiner Teile im Laufe der Zeit stattfindet. Weitere Informationen hierzu finden Sie in der Oracle-Dokumentation unter Implicit and Synthetic Parameters.