13

Nach vielen Stunden der Recherche bin ich endlich offizielle Hilfe konsultieren.RecyclerView.onBindViewHolder nur einmal aufgerufen

Ich habe einen RecyclerView.Adapter und RecyclerView.ViewHolders, die perfekt funktionierte. Aber aus einigen Gründen, die ich nicht verstehe, RecyclerView.Adapter.onBindViewHolder wird nicht ordnungsgemäß aufgerufen.

private class AttendeeAdapter extends RecyclerView.Adapter<AttendeeHolder> { 
    /*FIELDS*/ 
    private List<Attendee> mAttendeeList; 

    /*CONSTRUCTORS*/ 
    public AttendeeAdapter(List<Attendee> attendees) { 
     mAttendeeList = attendees; 
     //Log.i(TAG, "AttendeeAdapter size: " + getItemCount()); 
    } 

Basierend auf der Log-Nachricht (das Einzelteil als die Größe der Liste zählt wie erwartet), gehe ich davon aus dem AttendeeAdapter richtig instanziiert wurde.

Also ich erwarte onBindViewHolder (VH, int) -Methode würde so oft wie die Größe der Liste aufgerufen werden, aber es ist nicht. Die Methode wird nur einmal aufgerufen!

/*METHODS*/ 
    @Override 
    public AttendeeHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); 
     View itemView = layoutInflater.inflate(R.layout.list_attendee, parent, false); 
     return new AttendeeHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(AttendeeHolder holder, int position) { 
     Attendee attendee = mAttendeeList.get(position); 
     holder.bindAttendee(attendee, position); 

     Log.i(TAG, "Binding ViewHolder #" + position); 
     /* Binding ViewHolder #0 and that's it */ 
    } 

    @Override 
    public int getItemCount() { 
     return mAttendeeList.size(); 
    } 
} 

Mein AttendeeHolder (Erweiterung RecyclerView.ViewHolder) geht wie folgt vor:

private class AttendeeHolder extends RecyclerView.ViewHolder { 
    /*FIELDS*/ 
    private EditText mAttendeeNameEditText; 
    private Attendee mAttendee; 

    /*CONSTRUCTOR*/ 
    public AttendeeHolder(View itemView) { 
     super(itemView); 
     mAttendeeNameEditText = (EditText) itemView.findViewById(R.id.edit_text_list_item); 
     mAmountEditTextList = new ArrayList<>(eventMaxCount); 
     } 

    /*METHODS*/ 
    public void bindAttendee(Attendee attendee, final int position) { 
     mAttendee = attendee; 
     String attendeeName = mAttendee.getName(); 

     // Set the name to the EditText if a name has already been set 
     if (attendeeName != null) { 
      mAttendeeNameEditText.setText(attendeeName); 
     } 
    } 
} 

und im Hauptcode als

List<Attendee> attendees = AttendeeLab.get().getAttendeeList(); 
    mAttendeeAdapter = new AttendeeAdapter(attendees); 
    mAmountRecyclerView.setAdapter(mAttendeeAdapter); 

ich den Code erraten umgesetzt funktionieren würde (ich glaube, Ich habe keine Änderung vorgenommen), aber die Abhängigkeiten der Tabelle sind möglicherweise nicht richtig eingestellt. Dort habe ich versucht, Recyclerview-v7: 23.3.0 auf Recyclerview-v7: 23.1.0 oder was auch immer zu ändern (keiner von ihnen hat funktioniert).

dependencies { 
compile fileTree(dir: 'libs', include: ['*.jar']) 
testCompile 'junit:junit:4.12' 
compile 'com.android.support:appcompat-v7:23.3.0' 
compile 'com.android.support:design:23.3.0' 
compile 'com.android.support:support-v4:23.3.0' 
compile 'com.android.support:recyclerview-v7:23.1.2' 
} 

Jede Hilfe oder Kommentar würde geschätzt. Ich wünschte, ich würde mich nach einigen Stunden von den Kopfschmerzen verabschieden.

+0

nicht sicher, ob es das alles bedeutet - aber wie wollen Sie Ihre 'AttendeeHolder' zugreifen, da es privat accessand es hat befindet sich nicht in Ihrem 'AttendeeAdapter' ..? Verwenden Sie dieselbe Version auch für die Support Packages in Ihrem 'build.gradle'. – yennsarah

+0

Der ViewHolder und der Adapter waren innerhalb des Hauptcodes daher zugänglich. – SHAHM

+0

Sie haben das Problem gelöst!RecyclerViews arbeiten ordnungsgemäß mit derselben (alten) Version für die Support Packages, d. H. V7: 23.1.2. Es tut mir leid, dass ich ein schlechtes Verständnis davon habe, wie Gradle funktioniert, aber soll es so funktionieren? Was ist, wenn ich darauf bestehe, RecyclerViews mit den neuen Bibliotheken recyclingview-v7: 23.3.0 zu verwenden? – SHAHM

Antwort

1

Verwenden Sie die gleichen Versionen für alle Support-Bibliotheken:

dependencies { 

compile fileTree(dir: 'libs', include: ['*.jar']) 

testCompile 'junit:junit:4.12' 
compile 'com.android.support:appcompat-v7:23.3.0' 
compile 'com.android.support:design:23.3.0' 
compile 'com.android.support:support-v4:23.3.0' 
compile 'com.android.support:recyclerview-v7:23.3.0' //<<< here 
} 

Auch die RecyclerView sollte mit dem 'com.android.support:design:23.3.0' Paket hinzugefügt werden - die Überschreibung des classor was Magie Gradle getan hat in den Build-Prozess mit diesem " duplicate "Paket hat möglicherweise Ihr Problem verursacht.

+0

Nein, es funktioniert nicht. onBindViewHolder wurde nur einmal aufgerufen. Eigentlich war die letzte Zeile des Codes wie das, was du vorgeschlagen hast, aber ich dachte, ich sollte bei der Bibliothek bleiben, die ich benutzt habe, also habe ich mich verändert, als ich gepostet habe. Reinigung und Neuaufbau des Projekts ändert das Ergebnis nicht. – SHAHM

63

Das Problem ist nicht in Ihrem Code. Stellen Sie sicher, dass Sie layout_height auf wrap_content von RecyclerView untergeordneten Element festlegen.

+2

Ich stimme zu, dass der Code ordnungsgemäß funktioniert. Ich habe die "Layout_Height" -Attribute der untergeordneten Elemente überprüft und festgestellt, dass sie alle auf 'wrap_content' gesetzt sind. Ich bin mir ziemlich sicher, dass das Problem um die Bibliotheken geht. – SHAHM

+0

Eigentlich trat diese Art von Problem auch in meinem Projekt auf und es funktionierte für mich. –

+0

Große Antwort. +1 – developer1011

2

Achten Sie auf das Verhalten in den RecyclerView-Zyklen onBindViewHolder. RecyclerView.ViewHolder position 0 itemView

android:layout_height="match_parent" 

belegt den aktuell angezeigten Bildschirm. Scroll und onBindViewHolder sollten ausgelöst werden, stellen Sie aber sicher, dass richtig eingestellt wurde.

Lösung:

android:layout_height="wrap_content" 

Lösung mit ConstraintLayout wie aufgeblasen itemView:

<?xml version="1.0" encoding="utf-8"?>  
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"><!-- IMPORTANT --> 
    <!-- ... --> 
</android.support.constraint.ConstraintLayout> 
Verwandte Themen