13

Dopo molte ore di ricerca, sto finalmente consultando l'aiuto ufficiale.RecyclerView.onBindViewHolder chiamato una sola volta

Ho un RecyclerView.Adapter e RecyclerView.ViewHolders che ha funzionato perfettamente. Ma per alcuni motivi non capisco, RecyclerView.Adapter.onBindViewHolder non viene chiamato correttamente.

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

Sulla base del messaggio di registro (il conteggio del prodotto come la dimensione della lista come previsto), suppongo che l'AttendeeAdapter era correttamente un'istanza.

Quindi mi aspetto che il metodo onBindViewHolder (VH, int) venga chiamato tante volte quante sono le dimensioni dell'elenco ma non lo è. Il metodo è chiamato solo una volta!

/*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(); 
    } 
} 

mio AttendeeHolder (estendendo RecyclerView.ViewHolder) va come il seguente:

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

e implementato nel codice principale

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

Credo che il codice avrebbe funzionato (credo Non ho apportato alcuna modifica) ma le dipendenze gradle potrebbero non essere impostate correttamente. È stato qui che ho provato a modificare recyclerview-v7: 23.3.0 su recyclerview-v7: 23.1.0 o qualsiasi altra cosa (nessuno di essi funzionava).

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

Qualsiasi aiuto o commento sarebbe apprezzato. Vorrei poter dire addio al mal di testa dopo diverse ore da ora.

+0

Non sono sicuro se questo significa niente - ma come si fa a accedere al 'AttendeeHolder', dal momento che ha privato accessand esso non si trova nel tuo 'AttendeeAdapter' ..? Inoltre, usa la stessa versione per i pacchetti di supporto nel tuo 'build.gradle'. – yennsarah

+0

ViewHolder e Adapter erano classi interne nel codice principale quindi accessibili. – SHAHM

+0

Hai risolto il problema!RecyclerViews funziona correttamente utilizzando la stessa (vecchia) versione per i pacchetti di supporto, ad esempio v7: 23.1.2. Mi dispiace di non aver capito bene come funziona Gradle, ma dovrebbe funzionare in questo modo? Cosa succede se insisto a utilizzare RecyclerViews con le nuove librerie recyclerview-v7: 23.3.0? – SHAHM

risposta

1

Utilizzare le stesse versioni per tutte le vostre librerie di supporto:

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 
} 

Inoltre, il RecyclerView dovrebbero essere aggiunti con il pacchetto 'com.android.support:design:23.3.0' - la sovrascrittura del classor qualunque magia Gradle ha fatto nel processo di generazione con questo " "duplicato" potrebbe aver causato il tuo problema.

+0

No, non funziona. onBindViewHolder è stato chiamato solo una volta. In realtà, l'ultima riga del codice era stata come quella che mi hai suggerito, ma ho pensato che dovevo attenermi alla libreria che usavo, così ho cambiato come ho postato. La pulizia e la ricostruzione del progetto non cambiano il risultato. – SHAHM

63

Il problema non è nel codice. Assicurati di impostare layout_height su wrap_content di elemento figlio RecyclerView.

+2

Sono d'accordo che il codice funzioni correttamente. Ho controllato gli attributi '' layout_height' degli elementi figlio e ho scoperto che sono tutti impostati su 'wrap_content'. Sono abbastanza sicuro che il problema riguardi le biblioteche. – SHAHM

+0

In realtà questo tipo di problema si è verificato anche nel mio progetto e ha funzionato per me. –

+0

Ottima risposta. +1 – developer1011

2

Fare attenzione al comportamento di onBindViewHolder nei cicli di RecyclerView. RecyclerView.ViewHolder posizione 0 itemView

android:layout_height="match_parent" 

occupa la schermata visualizzata corrente. Scroll e onBindViewHolder devono essere attivati, ma assicurarsi che getItemCount sia stato impostato correttamente.

Soluzione:

android:layout_height="wrap_content" 

Soluzione con ConstraintLayout come itemView gonfiato:

<?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> 
Problemi correlati