RecyclerView未显示适配器中的所有项目

时间:2016-06-11 18:29:21

标签: android android-recyclerview recycler-adapter

我通过检查项目在RecyclerView中的位置以及是否从onBindViewHolder()服务请求了更多项目,在我的REST中实现了无限滚动。如果项目的位置从列表末尾开始小于5,并且当前没有为更多项目发出请求,则会执行更多项目的请求。

@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缓慢滚动,无限滚动工作正常,但如果我很快滚动到最后,查询会抓取下一批项目,将它们添加到列表中,但{{1} }将不会移过曾经是lat项的项目,就像它是列表的末尾一样。疯狂的部分是,日志记录清楚地表明列表大于RecyclerView使其看起来如此,但它不会显示新项目。

以下4个日志是我快速滚动到RecyclerView底部时创建的最后4个日志:

RecyclerView

最后一个日志显示,在第24位 - 从第一个查询收到的最后一个项目 - 调用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()为50 - 第二批已收到25个项目并已添加到mItems.size()。 但是,我无法向下滚动过去的第24项。

关于为什么会发生这种情况的任何想法?

更新

以下是我收到mItems服务的响应时运行的代码:

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); } 现在识别出列表中有更多项目,因此无限滚动开始再次正常运行。但是如果我再次快速向下滚动,那么bug最终会重新出现,我必须导航到另一个片段并从中再次运行。

1 个答案:

答案 0 :(得分:0)

似乎问题是RealmSingleton.addToBottomOfUserFeedRealm(usersFeed)Item异步添加到我的适配器的RealmResults列表中 - Realm的一个功能 - 我正在调用{ {1}}就在它之后。所以,我正在通知适配器在新项目被插入之前插入了新项目。

所以我所做的是FUserFeed.sAdapter.notifyItemRangeInserted()addChangeListener(RealmChangeListener)并在其中调用mItems以确保仅在notifyItemRangeInserted()更改后才调用它。

现在它完美无缺;无论我向下滚动多快。

虽然为什么它在我慢慢滚动时起作用仍然很奇怪。滚动速度不会影响mItems将项目异步添加到Realm的速度,因此在将项目实际添加到列表之前应始终调用mItems。然而,如果我滚动得足够慢,那么实现仍然有效。