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 }
val itemCount = adapter.itemCount val lastVisiblePosition = layoutManager.findLastVisibleItemPosition() val isNearBottom = itemCount > 2 && lastVisiblePosition >= itemCount - 2
val shouldShow = isScrollingDown && totalScrollDownDistance > 200 && !isNearBottom
if (shouldShow != hasScrolledUp) { hasScrolledUp = shouldShow scrollToEndBtn.isVisible = shouldShow }
lastScrollOffset = currentScrollOffset }
|
2. 底部不可见高度大于600像素,出现【回到底部】按钮
✅ 显示条件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
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 } }
|