RecyclerView上滑显示【回到底部】按钮

RecyclerView上滑显示【回到底部】按钮

在 RecyclerView 中的 onScrolled 方法中实现回到底部按钮的显示逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

private var isUserScrolling = false
private var hasScrolledUp = false // 是否向上滚动
private var lastScrollOffset = 0 // 上次滚动位置
private var isScrollingDown = false // 是否向下滚动
private var totalScrollDownDistance = 0 // 累计向下滚动距离

recyclerView.apply {
this.layoutManager = layoutManager
this.adapter = adapter

itemAnimator = null

// 添加滚动监听,检测用户手动滚动
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
Log.d(TAG, "onScrollStateChanged: newState=$newState")
isUserScrolling = newState != RecyclerView.SCROLL_STATE_IDLE
}

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
handleScrollChanged(dy)
}
})
}

scrollToEndBtn.setOnClickListener {
val itemCount = adapter.itemCount
if (itemCount > 0) {
recyclerView.smoothScrollToPosition(itemCount - 1)
}
}

1. 累计下滑距离超过200像素,出现【回到底部】按钮

✅ 显示条件:

  • 用户向下滚动,通过 dy 参数检测滚动方向(正值=向下,负值=向上)
  • 累计下滑距离超过200像素
  • 最后2条Item不可见
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 处理滚动变化
*/
private fun handleScrollChanged(dy: Int) {
val currentScrollOffset = recyclerView.computeVerticalScrollOffset()

// 检测滚动方向
if (dy > 0) {
// 向下滚动 (正值表示向下)
isScrollingDown = true
totalScrollDownDistance += dy
} else if (dy < 0) {
// 向上滚动 (负值表示向上)
isScrollingDown = false
// 重置累计向下滚动距离
totalScrollDownDistance = 0
}

// 检查最后2条Item是否可见
val itemCount = adapter.itemCount
val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()
val isNearBottom = itemCount > 2 && lastVisiblePosition >= itemCount - 2

// 当向下滚动累计超过200时显示按钮,但如果最后2条Item可见则隐藏
val shouldShow = isScrollingDown && totalScrollDownDistance > 200 && !isNearBottom

if (shouldShow != hasScrolledUp) {
hasScrolledUp = shouldShow
scrollToEndBtn.isVisible = shouldShow
}

lastScrollOffset = currentScrollOffset
}

2. 底部不可见高度大于600像素,出现【回到底部】按钮

✅ 显示条件:

  • 底部不可见高度大于600像素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 当页面底部不可见高度大于600像素,出现该btn
*/
private fun handleScrollChanged() {
// 检查底部不可见内容高度
val scrollRange = recyclerView.computeVerticalScrollRange() // 总内容高度
val scrollExtent = recyclerView.computeVerticalScrollExtent() // 可见区域高度
val scrollOffset = recyclerView.computeVerticalScrollOffset() // 当前滚动位置
val bottomInvisibleHeight = scrollRange - scrollExtent - scrollOffset // 底部不可见高度
val shouldShow = bottomInvisibleHeight >= 600 // 是否接近底部

if (shouldShow != hasScrolledUp) {
hasScrolledUp = shouldShow
scrollToEndBtn.isVisible = shouldShow
}
}
作者

Dench

发布于

2025-09-18

更新于

2025-09-18

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×