2016-06-11 6 views
1

RecyclerViewにアイテムの位置を確認してonBindViewHolder()に無限スクロールを実装し、RESTサービスからさらにアイテムが要求されているかどうかを確認しました。アイテムの位置がリストの最後から5未満であり、現在より多くのアイテムに対してリクエストが行われていない場合、より多くのアイテムのリクエストが実行されます。RecyclerViewがアダプタ内のすべてのアイテムを表示していません

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

RecyclerViewがゆっくりをスクロールされた場合に無限スクロールが正常に動作しますが、私は本当にすぐ最後までスクロールすると、クエリは、アイテムの次のバッチをつかむリストに追加されますが、RecyclerViewはしませんリストの最後であるかのように、latアイテムになっていたアイテムを移動します。クレイジーな部分は、リストがRecyclerViewよりも大きいことがログに表示されているように見えるが、新しい項目を表示しないことは明らかです。私は非常に迅速にRecyclerViewの一番下までスクロールすると

ザ・4以下のログが作成され、最後の4です:

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 

最後のログがonBindViewHolder()は、位置24でのアイテムのために呼ばれたことを示している - 最後の項目最初のクエリから受信した - その時点でmItems.size()は50です - 25個のアイテムの2番目のバッチが受信され、mItemsに追加されました。 しかし、これ以上過去のアイテム24はスクロールできません。

これはどうして起こっているのでしょうか?

アップデート:ここで

私はRESTサービスからの応答を受信したときに実行されるコードです:

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

更新: もっと奇妙な行動 - 私は別のに移動するときフラグメントを作成してユーザーのフィードフラグメントに戻すと、RecyclerViewはリストに項目があると認識し、無限スクロールが再び正しく動作するようになります。しかし、私が非常に素早く再び下にスクロールすると、バグが再び発生し、別のフラグメントに移動して、それを再び動作させる必要があります。

+0

'inserted'の代わりに 'notifyDataSetChanged'を試しましたか?ちょうどその場合 –

+0

@StasLelyukいいえ、しかし私は問題を解決しました。私は問題の原因を理解したかどうかはわかりませんが、無限のスクロールは関係なく動作しています。私の答えをチェックする –

答えて

0

問題がRealmSingleton.addToBottomOfUserFeedRealm(usersFeed)非同期に私のアダプタのRealmResultsリストにItem秒を追加したように思える - Realmの機能を - と、私は右のそれの後FUserFeed.sAdapter.notifyItemRangeInserted()を呼んでいました。そこで、新しい項目が挿入される前に新しい項目が挿入されたことをアダプタに通知していました。

だから何私がやったことはmItemsからaddChangeListener(RealmChangeListener)であり、mItemsが変更された後にのみ呼ばれていますことを確認するために、その中にnotifyItemRangeInserted()と呼ばれます。

今は完全に機能しています。どんなに速くスクロールしても問題ありません。

私はゆっくりとスクロールしたときになぜそれがうまくいったのですかはまだ変わっています。 Realmが項目を非同期でmItemsに追加する速度にスクロール速度は影響しません。したがって、項目が実際にリストに追加される前に常にnotifyItemRangeInserted()が呼び出されていたはずです。それでも、私が十分にゆっくりとスクロールすると、実装はまだ機能しました。

関連する問題