Я столкнулся с той же проблемой и нашел простое решение, которое не требует рефакторинга с использованием библиотеки, предложенной asif-ali.
В моем текущем проекте у меня есть NestedScrollView
, который содержитConstraintLayout
.Этот ConstraintLayout
содержит сложный заголовок, состоящий из нескольких представлений, а затем мой RecyclerView
.
Так же, как и вы, мне нужно было прокрутить все это.
Тем не менее, когда пользователь хочет видеть элемент из определенного RecyclerView
, вы обычно вызываете:
RecyclerView # smoothScrollToPosition (int position)
Нопоскольку высота RecyclerView
установлена на wrap_content
, отображается полный список с ViewHolder
с количеством элементов в adapter
.Конечно, мы не извлекаем выгоду из переработки, но тогда зачем нам нужен ScrollView
?Использование решения @ asif-ali, безусловно, может привести к оптимизации переработки, но здесь дело не в этом.
Итак, у нас есть полностью выложенное RecyclerView
.Для того чтобы перейти к позиции определенного элемента (ViewHolder#itemView
), вы можете сделать следующее:
final void smoothScrollToPosition(final int position) {
final ViewHolder itemViewHolder = this.recyclerView.findViewHolderForAdapterPosition(position);
// at this point, the ViewHolder should NOT be null ! Or else, position is incorrect !
final int scrollYTo = (int) itemViewHolder.itemView.getY();
// FYI: in case of a horizontal scrollview, you may use getX();
this.nestedScrollView.smoothScrollTo(
0, // x - for horizontal
scrollYTo
);
}
Вот и все!Вполне возможно, что потомок не полностью виден после этого (в моем тестовом примере), поэтому я бы предложил добавить половину высоты itemView к переменной scrollYTo
, чтобы nestedScrollView
прокручивал достаточно.Если вы это сделаете, вы также можете проверить, в каком направлении nestedScrollView
необходимо прокрутить (вверх, затем удалить половину высоты или вниз, а затем добавить половину высоты.
[РЕДАКТИРОВАТЬ1]
После дальнейшего тестирования и исследования, основанного на этом ответе: https://stackoverflow.com/a/6831790/3535408 на самом деле лучше и проще нацелиться на itemView.getBottom
. В моем приложении это работает безупречно.
Итак, обновленный код выглядит следующим образом:
final void smoothScrollToPosition(final int position) {
final ViewHolder itemViewHolder = this.recyclerView.findViewHolderForAdapterPosition(position);
// at this point, the ViewHolder should NOT be null ! Or else, position is incorrect !
// FYI: in case of a horizontal scrollview, you may use getX();
this.nestedScrollView.smoothScrollTo(
0, // x - for horizontal
itemViewHolder.itemView.getBottom()
);
}