2016-06-11 1 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, похоже, что он выглядит, но он не отображает новые элементы.

В приведенной ниже 4 бревна последний 4 создается, когда я прокручиваю в нижней части RecyclerView очень быстро:

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 предметов получена и добавлена ​​к mItems. Тем не менее, я не могу прокрутить вниз по любому последующему элементу 24.

Любые идеи о том, почему это может происходить?

.

Update:

Вот код, который работает, когда я получаю ответ от 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

Вы пытались «notifyDataSetChanged» вместо «вставлен»? На всякий случай –

+0

@StasLelyuk нет, но я решил проблему. Я не уверен, понял ли я причину проблемы, но бесконечная прокрутка работает независимо. проверить мой ответ –

ответ

0

Похоже, проблема была RealmSingleton.addToBottomOfUserFeedRealm(usersFeed) добавлял Item S в RealmResults список моего адаптера асинхронно - особенность Realm - и я звоню FUserFeed.sAdapter.notifyItemRangeInserted() сразу после него. Итак, я уведомлял адаптер о том, что новые элементы были вставлены до того, как новые элементы были вставлены.

Так что я сделал addChangeListener(RealmChangeListener) к mItems и назвал notifyItemRangeInserted() в нем, чтобы гарантировать, что она вызывается только после того, как mItems изменилось.

Теперь он отлично работает; независимо от того, как быстро я прокручиваю вниз.

Это все еще странно, но почему это сработало, когда я медленно прокручивался. Скорость прокрутки не влияет на скорость, с которой Realm асинхронно добавляет элементы к mItems, поэтому notifyItemRangeInserted() должен был всегда вызываться до того, как элементы были фактически добавлены в список. И все-таки реализация продолжалась, если я прокручиваю достаточно медленно.