Recyclerview中最后一个可见Item的位置以及是否滑动到底部

本文介绍了如何在Android开发中准确判断RecyclerView是否滑动到底部,包括不同LayoutManager下的实现方式及避免误判的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前很多项目里都使用Recyclerview来做开发了,但是对于Recyclerview不是很了解可能会遇到各种问题,下面就对怎样判断Recyclerview中的最后一个item做判断!

  1. mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
  2. @Override
  3. public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  4. //当前RecyclerView显示出来的最后一个的item的position
  5. int lastPosition = -1;
  6.  
  7. //当前状态为停止滑动状态SCROLL_STATE_IDLE时
  8. if(newState == RecyclerView.SCROLL_STATE_IDLE){
  9. RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
  10. if(layoutManager instanceof GridLayoutManager){
  11. //通过LayoutManager找到当前显示的最后的item的position
  12. lastPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
  13. }else if(layoutManager instanceof LinearLayoutManager){
  14. lastPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
  15. }else if(layoutManager instanceof StaggeredGridLayoutManager){
  16. //因为StaggeredGridLayoutManager的特殊性可能导致最后显示的item存在多个,所以这里取到的是一个数组
  17. //得到这个数组后再取到数组中position值最大的那个就是最后显示的position值了
  18. int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
  19. ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(lastPositions);
  20. lastPosition = findMax(lastPositions);
  21. }
  22.  
  23. //时判断界面显示的最后item的position是否等于itemCount总数-1也就是最后一个item的position
  24. //如果相等则说明已经滑动到最后了
  25. if(lastPosition == recyclerView.getLayoutManager().getItemCount()-1){
  26. Toast.makeText(RecyclerActivity.this, "滑动到底了", Toast.LENGTH_SHORT).show();
  27. }
  28.  
  29. }
  30. }
  31.  
  32. @Override
  33. public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  34.  
  35. }
  36.  
  37. });

findMax方法:

  1. //找到数组中的最大值
  2. private int findMax(int[] lastPositions) {
  3. int max = lastPositions[0];
  4. for (int value : lastPositions) {
  5. if (value > max) {
  6. max = value;
  7. }
  8. }
  9. return max;
  10. }

        通过添加对RecyclerView的滑动事件,在滑动状态改变的回调里当滑动停止的时候通过layout找到当前RecyclerView显示的最后一个item的position,然后判断这个position是否为Recyclerview的最后一个item的position值,如果是的话则表示已经滑动到最底部了。
上面的代码基本上已经实现了对滑动到底部的监听,只需要将上面的Toast弹出提示的代码替换成我们自己的处理就可以了。但是上面的代码也有一个bug,当最后一个item刚显示出来的时候停止滑动这个时候也会触发滑动到底部的操作,有时候我们可能并不希望这,希望当Recyclerview确实是滑动到底部滑动不了的时候才触发。
修改上面的代码如下:

  1. mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
  2. @Override
  3. public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  4.  
  5. }
  6.  
  7. @Override
  8. public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  9.  
  10. //得到当前显示的最后一个item的view
  11. View lastChildView = recyclerView.getLayoutManager().getChildAt(recyclerView.getLayoutManager().getChildCount()-1);
  12. //得到lastChildView的bottom坐标值
  13. int lastChildBottom = lastChildView.getBottom();
  14. //得到Recyclerview的底部坐标减去底部padding值,也就是显示内容最底部的坐标
  15. int recyclerBottom = recyclerView.getBottom()-recyclerView.getPaddingBottom();
  16. //通过这个lastChildView得到这个view当前的position值
  17. int lastPosition = recyclerView.getLayoutManager().getPosition(lastChildView);
  18.  
  19. //判断lastChildView的bottom值跟recyclerBottom
  20. //判断lastPosition是不是最后一个position
  21. //如果两个条件都满足则说明是真正的滑动到了底部
  22. if(lastChildBottom == recyclerBottom && lastPosition == recyclerView.getLayoutManager().getItemCount()-1 ){
  23. Toast.makeText(RecyclerActivity.this, "滑动到底了", Toast.LENGTH_SHORT).show();
  24. }
  25. }
  26.  
  27. });
当最后一个item的高度放不下的时候需要使用下面的方法来做判断。
//获取最后一个完全显示的ItemPosition  
int lastVisibleItem = lineanrManager.findLastCompletelyVisibleItemPosition();  
int totalItemCount = lineanrManager.getItemCount();

如果你想要实现 RecyclerView 顶部和底部的圆角效果,并且在滑动 item 到顶部时不能出现直角,可以使用一个自定义的 ItemDecoration 来实现。 具体步骤如下: 1. 定义一个自定义的 ItemDecoration,重写 getItemOffsets() 方法,设置 RecyclerView 的 padding 值: ``` class CustomItemDecoration(private val margin: Int, private val radius: Int) : RecyclerView.ItemDecoration() { override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { super.getItemOffsets(outRect, view, parent, state) val pos = parent.getChildAdapterPosition(view) if (pos == 0) { outRect.top = radius } outRect.left = margin outRect.right = margin outRect.bottom = margin if (pos == state.itemCount - 1) { outRect.bottom = radius } } } ``` 2. 在 RecyclerView 的布局文件中,设置 RecyclerView 的背景为一个带有圆角的 ShapeDrawable,并且设置 RecyclerView 的 padding 为圆角大小: ``` <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/rounded_background" android:paddingTop="20dp" android:paddingBottom="20dp" /> ``` 3. 最后,在 RecyclerView 中设置自定义的 ItemDecoration: ``` val itemDecoration = CustomItemDecoration( resources.getDimensionPixelSize(R.dimen.margin), resources.getDimensionPixelSize(R.dimen.radius) ) recyclerView.addItemDecoration(itemDecoration) ``` 其中,margin 是 RecyclerView item 之间的间距,radius 是 RecyclerView 顶部和底部的圆角大小。 通过这种方式,你可以实现 RecyclerView 顶部和底部的圆角效果,并且在滑动 item 到顶部时不会出现直角。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值