2016-02-09 16 views
5

Ho un RecyclerView che im cercando di implementare una funzione di scroll infinito in. Il problema è che il codice all'interno delle istruzioni if ​​nel metodo viene eseguito due volte. Heres il mio codice corrente:RecyclerView Infinite Scroll ascoltatore viene chiamato due volte

public abstract class InfiniteScroll extends RecyclerView.OnScrollListener { 

private LinearLayoutManager mLayoutManager; 
private int previousTotal = 0; 
private boolean loading = true; 
private int visibleThreshold = 5; 
int firstVisibleItem, visibleItemCount, totalItemCount; 

private int current_page = 1; 

public InfiniteScroll(LinearLayoutManager layoutManager) { 
    mLayoutManager = layoutManager; 
} 

@Override 
public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 

    visibleItemCount = recyclerView.getChildCount(); 
    totalItemCount = mLayoutManager.getItemCount(); 
    firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition(); 

    if (loading) { 
     if (totalItemCount > previousTotal) { 
      loading = false; 
      previousTotal = totalItemCount; 
     } 
    } 
    if (!loading && (totalItemCount - visibleItemCount) 
      <= (firstVisibleItem + visibleThreshold)) { 
     // End has been reached 

     // Do something 
     current_page++; 
     Log.d("moreitems", "why is this being called twice?"); 
     loadMore(current_page); 

     loading = true; 
    } 
} 

public abstract void loadMore(int current_page); 
} 

Questo codice è stato inviato come una risposta ad una domanda separata SO, e altri esempi sembrano funzione simile, ma ho ancora il metodo loadMore() eseguendo due volte quando raggiunge il fondo del RecyclerView, e non sono sicuro del perché.

+0

utilizzare 'LimearLayoutManager # findLast [Completely] Metodo VisibleItemPosition()' – pskink

risposta

0

Prova questa:

public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       super.onScrolled(recyclerView, dx, dy); 
       final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); 
       totalItemCount = linearLayoutManager.getItemCount(); 
       lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition(); 
       if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) { 
        loading = true; 
        // End has been reached 
        // Do something 
         current_page++; 
         Log.d("moreitems", "why is this being called twice?"); 
         loadMore(current_page); 

       } 
      } 
+0

Dove si imposta il caricamento su 'false' con questa soluzione? Altrimenti il ​​caricamento rimane 'true' e di nuovo alla fine della lista non innescherà un altro carico. – Orbit

+0

Mi hanno inviato un codice di esempio qui: http: //stackoverflow.com/questions/35253695/recyclerview-load-more-with-progressbar-error/35254285#35254285 – Sabari

+0

Aggiungi carico = false; nel metodo loarmore() (ultima riga). Dovresti caricare su false dopo che tutto il materiale è stato completato. – Sabari

7

Sta diventando chiamato perché quando si loadMore articoli, onScrolled viene chiamato di nuovo.

Questo callback verrà chiamato anche se l'intervallo di elementi visibili cambia dopo un calcolo del layout. In tal caso, dx e dy sarà 0.

così si potrebbe verificare if (!loading && dy>0) così

+1

Grazie, lavora per me! –

+2

Btw, l'ho aggiunto all'inizio di 'onScrolled' quindi non verrà eseguito nulla, c'è un motivo per cui lo hai usato con'! Loading' ?, ho visto che può andare con '! Loading' ma perché? per eseguire il codice intermedio, va bene lo ho spostato verso l'alto come: 'if (dy <= 0) return;', voglio dire che non ho visto alcun problema con il mio codice ma forse si sono imbattuti in alcuni rari casi? –

-1

Ho appena incontrato situazione simile, mentre la soluzione è del tutto diversa da quella risposta di cui sopra.

Nel mio caso, ho un RecyclerViewFragment personalizzato, che sarà istituito RecyclerView all'inizio di roba caricamento dei dati. E aggiungo un OnScrollListener personalizzato al blocco del metodo impostato.

La ragione per cui OnScrollListener stato chiamato due volte a dire, ho accidentalmente aggiungere due OnScrollListener alla mia RecyclerView. Quindi questi due ascoltatori ascolteranno entrambi l'azione "scroll to the end" e faranno qualcosa per esso.

Quindi, rimuovo tutto il OnScrollListener per il mio RecyclerView prima di chiamare il metodo di installazione, per assicurarmi che ci sia solo un OnScrollListener.

Spero che questo aiuto.

0
if (layoutManager.findLastCompletelyVisibleItemPosition() == 
recyclerAdapter.getItemCount() - 1) { 
    //load more items code is here 
} 

Questo funzionerà.

Problemi correlati