首页 > 解决方案 > 滚动 Android RecyclerView 并控制屏幕上的确切位置

问题描述

我正在寻找一种以编程方式缓慢滚动 RecyclerView 的方法,以便将某个元素 targetPosition 准确地放在屏幕中间。请注意,我在 RecylerView 中的所有项目在设计上都具有相同的高度。RecyclerView 是垂直的。我在 Kotlin 和 AndroidX 编程

我努力了:

smoothScrollToPosition(targetPosition)

它滚动缓慢(我也可以通过扩展 LinearLayoutManager 和覆盖 calculateSpeedPerPixel() 来控制速度 - 请参阅如何控制 recyclerView.smoothScrollToPosition(position) 的滚动速度),但是我无法控制滚动后屏幕上的列表项。我所知道的是它将在屏幕上完全可见。

我努力了:

scrollToX(0, targetPosition * itemHeight - screenHeight / 2)

它给了我错误消息:“W/RecyclerView:RecyclerView 不支持滚动到绝对位置。改用 scrollToPosition”

我还尝试用包含所有子项的 LinearLayoutManager 替换 RecyclerView,并在视图中翻译 LinearLayoutManager,但我最初并没有让子项在屏幕之外进行绘制。

这个问题有解决方案吗?

标签: androidkotlinandroid-recyclerviewscrollandroidx

解决方案


您可以根据您的实际目标位置和可见项目的数量来计算smoothScrollToPosition's targetPosition。

关于如何做到这一点的快速 POC:

  val scrollToPosition = 50

  val layoutManager = recyclerView.layoutManager as LinearLayoutManager
  val firstPosition = layoutManager.findFirstVisibleItemPosition()
  val lastPosition = layoutManager.findLastVisibleItemPosition()
  val visibleItems =  lastPosition - firstPosition + 1

  if (firstPosition < scrollToPosition) {
      recyclerView.smoothScrollToPosition(scrollToPosition + (visibleItems / 2))
  } else {
      recyclerView.smoothScrollToPosition(scrollToPosition - (visibleItems / 2))
  }

如果你想要更精确的结果,项目应该正好在屏幕的中间,你可以使用项目的高度(因为它是固定的)和 RecyclerView 的高度,然后计算滚动的偏移量。并调用:

recyclerView.scrollBy(dx, dy)

或者:

recyclerView.smoothScrollBy(dx, dy)

推荐阅读