2016-01-26 62 views
13

我有一个RecyclerView,我在RecyclerView中添加了数据列表。当最后一个RecyclerView项目在屏幕上可见时,我想添加新数据。之后,我想进行Web服务调用并更新RecyclerView数据。我怎样才能做到这一点?如何识别RecyclerView的最后一项在屏幕上可见?

有什么建议吗?

+1

使用'android.support.v7.widget.RecyclerView.OnScrollListener' – pskink

+0

我知道滚动监听器,但我的问题是当用户删除项目之间,然后如何知道我的最后一个列表项是可见的,所以我可以更新列表或者拨打网络服务电话? –

+0

所以用'onBindViewHolder'然后 – pskink

回答

1

这对我有效,我已经使用过使用recycleview滚动监听器来实现这一点:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       LinearLayoutManager layoutManager=LinearLayoutManager.class.cast(recyclerView.getLayoutManager()); 
       int totalItemCount = layoutManager.getItemCount(); 
       int lastVisible = layoutManager.findLastVisibleItemPosition(); 

       boolean endHasBeenReached = lastVisible + 5 >= totalItemCount; 
       if (totalItemCount > 0 && endHasBeenReached) { 
        //you have reached to the bottom of your recycler view 
       } 
      } 
     }); 

谢谢。

+0

是的,这似乎被接受的答案..简单和较少的解决方法需要+1 –

15

有几种方法可以做到这一点,但一个方法是使用适配器的onBindViewHolder方法:

@Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
     if (position == mData.length - 1) { 
      // load more data here. 
     } 

     /// binding logic 
    } 

当绑定方法被调用与数据源的最后一个位置,这是一个很好指示即将显示最后一个小区并且触发重新加载呼叫的好时机。您可能需要为条件添加额外的安全措施,以确保您尚未加载更多数据,但这应该有助于您开始使用。

另一个选项将涉及编辑您的LayoutManager。这里的想法是找到最后一个可见项目的位置。如果该位置等于数据集的最后一项,则应该触发重新加载。这一呼吁应该在你的LayourManager'sonLayoutChildren & scrollVerticallyBy(假设你使用垂直滚动)方法来完成:

@Override 
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { 

     final int result = super.scrollVerticallyBy(dy, recycler, state); 

     if (findLastVisibleItemPosition() == mData.length - 1) { 
      loadMoreData(); 
     } 

     return result; 

    } 

    @Override 
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 
     super.onLayoutChildren(recycler, state); 

     if (findLastVisibleItemPosition() == mData.length - 1) { 
      loadMoreData(); 
     } 
    } 

以前一样,你需要确保你不会触发数据负载超过一次,因为这种情况可能会不止一次发生。

希望这有助于!

+0

我记得recyclerview将有更多的视图绑定,将在屏幕之外。所以,我认为检查最后一个项目可能不会帮助 – cgr

+0

当视图即将变得可见时它会绑定它,所以我相信它应该足够好。我将添加另一个选项tho –

+0

是的,当它变得可见时它会绑定。所以,绑定的最后一个不需要已经可见。所以,我们仍然需要条件来检查可见性。 他也可以在LinearLayoutManager中尝试findLastVisibleItemPosition()。 – cgr

3

如果有人越过这个职位this is绊倒如何做到这一点的快速和简单的教程:

所有你需要做的是:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
    @Override 
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
     super.onScrollStateChanged(recyclerView, newState); 
    } 

    @Override 
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
     super.onScrolled(recyclerView, dx, dy); 
     int visibleItemCount  = lm.getChildCount(); 
     int totalItemCount   = lm.getItemCount(); 
     int firstVisibleItemPosition= lm.findFirstVisibleItemPosition(); 

     // Load more if we have reach the end to the recyclerView 
     if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) { 
      loadMoreItems(); 
     } 
    } 
}); 

那么你loadMoreItems()看起来应该是像这样:

private void loadMoreItems() { 
    // init offset=0 the frist time and increase the offset + the PAGE_SIZE when loading more items 
    queryOffset = queryOffset + PAGE_SIZE; 
    // HERE YOU LOAD the next batch of items 
    List<Items> newItems = loadItems(queryOffset, PAGE_SIZE); 

    if (newItems.size() > 0) { 
     items.addAll(newItems); 
     adapter.notifyDataSetChanged(); 
    } 
} 
0
@Override 
public void onBindViewHolder(final RecyclerView.ViewHolderholder, int position) { 

    if (!list.isEmpty() || list== null) { 

     if (position == (list.size() - 1)) { 

      // add new data (add data to list) 
      this.notifyDataSetChanged(); 

     } 

    } 


} 
相关问题