2016-06-11 17 views
1

Ich implementierte unendlich scrollen in meinem RecyclerView indem Sie die Position des Artikels in onBindViewHolder() überprüfen und ob weitere Artikel vom REST Service angefordert werden. Wenn die Position des Artikels weniger als 5 vom Ende der Liste entfernt ist und keine Anfrage für weitere Artikel gestellt wird, wird eine Anfrage für weitere Artikel ausgeführt.RecyclerView zeigt nicht alle Elemente im Adapter an

@Override 
public void onBindViewHolder(ItemHolder holder, int position) { 
    holder.bindHolder(position); 

    //debugging purposes 
    //logs the current position, the size of the item list, and whether 
    //or not more items are already being retrieved from the rest service 
    Log.d("ADAPTER", "position = " + position + 
        "\nmItems.size() = " + mItems.size() + 
        "\nGET_USER_FEED_IS_INACTIVE = " + 
        HTTPRequests.GET_USER_FEED_IS_INACTIVE + "\n\n"); 

    //query for more items if the user is less than 5 items from the end and 
    //there is not already an active query 
    if (position > mPolls.size() - 5 && HTTPRequests.GET_USER_FEED_IS_INACTIVE){ 
     HTTPRequests.GETUsersFeed(); 
    } 
} 

Infinite Scrolling funktioniert gut, wenn die RecyclerView durch langsam gescrollt wird, aber wenn ich wirklich schnell zu Ende bewegen, greift die Abfrage die nächste Charge von Elementen, fügt sie der Liste, aber das wird nicht RecyclerView Bewegen Sie sich an dem Element vorbei, das das letzte Element war, als wäre es das Ende der Liste. Der verrückte Teil ist, dass es mit der Protokollierung klar ist, dass die Liste größer ist als die RecyclerView, scheint es zu erscheinen, aber es werden die neuen Elemente nicht angezeigt.

Die unter 4 Protokolle sind die letzten 4 erstellt, wenn ich sehr schnell auf den Boden der RecyclerView blättern:

D/ADAPTER: position = 20 
      mItems.size() = 50 
      GET_USER_FEED_IS_INACTIVE = true 

D/ADAPTER: position = 19 
      mItems.size() = 50 
      GET_USER_FEED_IS_INACTIVE = true 

D/ADAPTER: position = 23 
      mItems.size() = 50 
      GET_USER_FEED_IS_INACTIVE = true 

D/ADAPTER: position = 24 
      mItems.size() = 50 
      GET_USER_FEED_IS_INACTIVE = true 

Das letzte Protokoll zeigt, dass onBindViewHolder() für Punkt an Position 24 genannt wurde - der letzte Punkt erhalten von der ersten Abfrage - und zu dieser Zeit mItems.size() ist 50 - die zweite Charge von 25 Artikel wurde empfangen und mItems hinzugefügt. Ich kann jedoch keinen weiteren letzten Punkt 24 nach unten scrollen.

Irgendwelche Ideen, warum dies passieren könnte?

.

Update:

Hier ist der Code, der ausgeführt wird, wenn ich die Antwort von dem REST Service erhalten:

public void onResponse(String response) { 
     List<Item> usersFeed = sGson.fromJson(response, new TypeToken<ArrayList<Item>>(){}.getType()); 

     //get the size of the adapter's list before new items are added 
     int initialNumberOfItemsInAdapter = FUserFeed.sAdapter.getItemCount(); 

     //add new items to adapter's list 
     RealmSingleton.addToBottomOfUserFeedRealm(usersFeed); 

     //notify adapter of the new items 
     FUserFeed.sAdapter 
       .notifyItemRangeInserted(initialNumberOfItemsInAdapter, usersFeed.size()); 

     //signify the end of GETUserFeed activity 
     GET_USER_FEED_IS_INACTIVE = true; 
     Log.d("VOLLEY", response); 
} 

Update: Mehr seltsames Verhalten - wenn ich zu einem anderen navigieren Fragment und dann wieder zurück zum Benutzer Feed-Fragment, die RecyclerView erkennt nun, dass es mehr Elemente in der Liste gibt, so beginnt unendliche Scrolling wieder richtig zu verhalten. Aber wenn ich wieder sehr schnell nach unten scrolle, kommt der Fehler schließlich wieder, und ich muss zu einem anderen Fragment navigieren, um es wieder funktionieren zu lassen.

+0

Haben Sie 'notifyDataSetChanged' anstelle von 'eingefügt' versucht? Nur für den Fall –

+0

@StasLelyuk Nein, aber ich löste das Problem. Ich bin mir nicht sicher, ob ich die Ursache des Problems herausgefunden habe, aber das unendliche Scrollen funktioniert unabhängig davon. Schau dir meine Antwort an –

Antwort

0

Es scheint, wie das Problem war RealmSingleton.addToBottomOfUserFeedRealm(usersFeed) die Item s RealmResults Liste meines des Adapters asynchron hinzugefügt wurde - ein Feature von Realm - und ich rufe FUserFeed.sAdapter.notifyItemRangeInserted() direkt danach. Also habe ich dem Adapter mitgeteilt, dass neue Objekte eingefügt wurden, bevor neue Objekte eingefügt wurden.

Also, was ich tat, war addChangeListener(RealmChangeListener)-mItems und rief notifyItemRangeInserted() darin, sicherzustellen, dass es nur genannt nach mItems verändert hat.

Jetzt funktioniert es perfekt; egal wie schnell ich runterscrolle.

Es ist immer noch seltsam, warum es funktionierte, wenn ich langsam scrollte. Die Scrollgeschwindigkeit hat keinen Einfluss auf die Geschwindigkeit, mit der Realm asynchron Elemente zu mItems hinzugefügt wurden. Daher sollte notifyItemRangeInserted() immer aufgerufen worden sein, bevor die Elemente tatsächlich zur Liste hinzugefügt wurden. Und trotzdem funktionierte die Implementierung noch, wenn ich langsam genug scrollte.

Verwandte Themen