2016-02-09 18 views
5

Ich habe eine RecyclerView, die ich versuche, eine unendliche Scroll-Funktion zu implementieren. Das Problem ist, dass der Code innerhalb der if-Anweisungen in der OnScrolled-Methode zweimal ausgeführt wird. Heres meine aktuellen Code:RecyclerView Infinite Scroll Listener wird zweimal aufgerufen

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

Dieser Code als Antwort auf eine separate SO Frage gestellt wurde, und andere Beispiele scheinen ähnlich zu funktionieren, aber ich habe noch die loadMore() Methode zweimal ausgeführt wird erhalten, wenn die Unterseite des RecyclerView erreicht, und ich bin mir nicht sicher warum.

+0

Verwendung 'LimearLayoutManager # findLast [Completely] VisibleItemPosition()' Methode – pskink

Antwort

0

Try this:

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

Wo setzen Sie das Laden mit dieser Lösung auf 'false' zurück? Andernfalls bleibt das Laden "wahr" und das Erreichen des Endes der Liste wird nicht erneut eine Last auslösen. – Orbit

+0

Ich habe hier einen Beispielcode geschrieben: http: //stackoverflow.com/questions/35253695/recyclerview-load-more-with-progressbar-error/35254285#35254285 – Sabari

+0

Hinzufügen loading = false; in der loarmore() Methode (letzte Zeile). Sie sollten den Ladevorgang auf "false" setzen, nachdem alle Ihre Aufgaben abgeschlossen wurden. – Sabari

7

es heißt immer, weil, wenn Sie Elemente loadMore, onScrolled wieder aufgerufen wird.

Dieser Callback wird auch aufgerufen, wenn sich der sichtbare Bereich nach einer Layoutberechnung ändert. In diesem Fall dx und dy wird 0 sein

so konnte man if (!loading && dy>0) auch

überprüfen
+1

Danke, funktioniert für mich! –

+2

Btw, ich habe es am Anfang von 'onScrolled' hinzugefügt, damit nichts ausgeführt wird, gibt es einen Grund, warum du es mit dem'! Loading' benutzt hast? Ich habe gesehen, dass es auch mit '! Loading' gehen kann um dazwischen Code auszuführen, ist es in Ordnung, ich habe es nach oben bewegt wie: 'if (dy <= 0) return;', ich meine, ich habe kein Problem mit meinem Code gesehen, aber vielleicht hast du einige seltene Fälle? –

-1

ich ähnliche Situation gerade erst kennengelernt, während Lösung ganz anders als die oben genannte Antwort ist.

In meinem Fall habe ich eine benutzerdefinierte RecyclerViewFragment, die RecyclerView am Anfang der Daten laden Zeug einrichten wird. Und ich füge einen benutzerdefinierten OnScrollListener bei diesem Setup-Methodenblock hinzu.

Mein Grund, warum OnScrollListener zweimal aufgerufen wurde, ist, dass ich versehentlich zwei OnScrollListener zu meinem RecyclerView hinzufüge. So werden diese beiden Zuhörer beide Zuhörer auf die "Scroll-to-End" -Aktion aufmerksam machen und dafür etwas tun.

Also entferne ich einfach alle OnScrollListener für meine RecyclerView, bevor ich die Methode einrichte, um sicherzustellen, dass es nur einen OnScrollListener gibt.

Hoffe diese Hilfe.

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

Dies wird funktionieren.