RecyclerView LinearLayoutManager computeVerticalScrollOffset() не возвращает правильное значение
Я работаю с RecyclerView и соответствующим LinearLayoutManager. Я добавлял некоторые настраиваемые функции прокрутки в часть моего приложения, где я бы перевел пользовательский объект заголовка вместе со списком RecyclerView, смоделированным после этого проекта: https://github.com/boxme/ParallaxHeaderViewPager ( который использует ListView вместо RecyclerView).
Я столкнулся с странной проблемой. На некоторое время она прокручивается, но потом она скачет несколько сотен пикселей. Я добавил операторы журналов, чтобы увидеть смещение, вычисленное LinearLayoutManager.computeVerticalScrollOffset(), когда я прокрутил его достаточно уверенно, смещение было случайным образом перескакивает с 320 до 1200, после чего оно будет продолжать вычислять смещение соответственно с этой точки.
См. мой ответ ниже о том, как я это решил!
Ответы
Ответ 1
Проблема заключалась в том, что у меня был очень большой невидимый элемент в моем списке, за которым последовала куча мелких предметов. Оказывается, LinearLayoutManager.computeVerticalScrollOffset() учитывает среднюю высоту строки при расчете. Это вызвало у меня проблему, так как этот большой элемент наверху отбрасывал среднюю высоту строк. Я решил это решить, добавив несколько меньших невидимых предметов сверху, а не один большой, чтобы сохранить среднюю высоту строки.
Я надеюсь, что это поможет любому, кто сталкивается с подобной проблемой!
Ответ 2
Благодаря этой теме, наконец, нашли способ решить эту проблему, разместив ниже код для переопределенного LinearLayoutManager, извините за его kotlin :(, вы также можете прочитать об этом в более подробно здесь
class LinearLayoutManagerWithAccurateOffset(context: Context?) : LinearLayoutManager(context) {
// map of child adapter position to its height.
private val childSizesMap = mutableMapOf<Int, Int>()
override fun onLayoutCompleted(state: RecyclerView.State?) {
super.onLayoutCompleted(state)
for (i in 0 until childCount) {
val child = getChildAt(i)
childSizesMap[getPosition(child)] = child.height
}
}
override fun computeVerticalScrollOffset(state: RecyclerView.State?): Int {
if (childCount == 0) {
return 0
}
val firstChildPosition = findFirstVisibleItemPosition()
val firstChild = findViewByPosition(firstChildPosition)
var scrolledY: Int = -firstChild.y.toInt()
for (i in 0 until firstChildPosition) {
scrolledY += childSizesMap[i] ?: 0
}
return scrolledY
}
}