Как сохранить положение прокрутки RecyclerView в Android?
У меня есть вид Recycler, который лежит внутри SwipeRefreshLayout. Кроме того, есть возможность открывать каждый элемент в другом действии.
После возвращения обратно в Recycler мне нужно прокрутить выбранный элемент или предыдущий Y.
Как это сделать?
Да, я googled, нашел статьи в StackOverFlow о сохранении экземпляра менеджера макета, как этот: RecyclerView хранить/восстанавливать состояние между действиями.
Но мне это не помогает.
UPDATE
Сейчас у меня такая разрешающая проблема, но, конечно, она также не работает.
private int scrollPosition;
...//onViewCreated - it is fragment
recyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(llm);
data = new ArrayList<>();
adapter.setData(getActivity(), data);
recyclerView.setAdapter(adapter);
...
@Override
public void onResume() {
super.onResume();
recyclerView.setScrollY(scrollPosition);
}
@Override
public void onPause() {
super.onPause();
scrollPosition = recyclerView.getScrollY();
}
Да, я попробовал scrollTo (int, int) - doen't work.
Теперь я попробовал просто прокрутить, например, до Y = 100, но он вообще не прокручивается.
Ответы
Ответ 1
Сохранить текущее состояние позиции возврата в цикл @onPause:
positionIndex= llManager.findFirstVisibleItemPosition();
View startView = rv.getChildAt(0);
topView = (startView == null) ? 0 : (startView.getTop() - rv.getPaddingTop());
Восстановите положение прокрутки @onResume:
if (positionIndex!= -1) {
llManager.scrollToPositionWithOffset(positionIndex, topView);
}
или другим способом может быть @onPause:
long currentVisiblePosition = 0;
currentVisiblePosition = ((LinearLayoutManager)rv.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
restore @onResume:
((LinearLayoutManager) rv.getLayoutManager()).scrollToPosition(currentVisiblePosition);
currentVisiblePosition = 0;
Ответ 2
Многие из этих ответов, похоже, усложняют его.
LayoutManager поддерживает onRestoreInstanceState
из коробки, поэтому нет необходимости сохранять позиции прокрутки и т.д. Встроенный метод уже сохраняет идеальные позиции пикселей.
Пример кода фрагмента (нулевая проверка и т.д. удалена для ясности):
private Parcelable listState;
private RecyclerView list;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listState=savedInstanceState.getParcelable("ListState");
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("ListState", list.getLayoutManager().onSaveInstanceState());
}
тогда просто вызовите
list.getLayoutManager().onRestoreInstanceState(listState);
как только ваши данные будут привязаны к вашему RecyclerView
Ответ 3
Пользователь вашего ресайклера viewlinelayoutmanager для получения положения прокрутки
int position = 0;
if (linearLayoutManager != null) {
scrollPosition = inearLayoutManager.findFirstVisibleItemPosition();
}
и при восстановлении используйте следующий код
if (linearLayoutManager != null) {
cardRecyclerView.scrollToPosition(mScrollPosition);
}
Надеюсь, это поможет вам
Ответ 4
чтобы сохранить позицию в настройках, добавьте это в свой onStop()
int currentVisiblePosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
getPreferences(MODE_PRIVATE).edit().putInt("listPosition", currentVisiblePosition).apply();
затем восстановить положение, как это
if (getItemCount() == 0) {
int savedListPosition = getPreferences(MODE_PRIVATE).getInt("listPosition", 0);
recyclerView.getLayoutManager().scrollToPosition(savedListPosition); }
последний код должен быть добавлен в событие Адаптера (не уверен, что это событие ведьмы, но в моем случае это onEvent() - com.google.firebase.firestore.EventListener)
Ответ 5
По некоторым причинам есть много вводящих в заблуждение советов/предложений о том, как сохранить и восстановить позицию прокрутки в your_scrolling_container при изменении ориентации.
Возьмите текущую позицию прокрутки и сохраните ее в Activitys onSaveInstanceState Расширение определенного прокручиваемого представления, чтобы сделать то же самое там. Предотвращение разрушения Activity при вращении И да, они работают нормально, но…
Но на самом деле все гораздо проще, потому что Android уже делает это за вас!
Если вы внимательно посмотрите на источники RecyclerView/ListView/ScrollView/NestedScrollView, вы увидите, что каждый из них сохраняет свою позицию прокрутки в onSaveInstanceState. И во время первого прохода макета они пытаются прокрутить до этой позиции в методе onLayout.
Есть только 2 вещи, которые нужно сделать, чтобы убедиться, что все будет работать нормально:
-
Установите идентификатор для вашего прокручиваемого представления, что, вероятно, уже сделано. В противном случае Android не сможет автоматически сохранять состояние просмотра.
-
Предоставьте данные перед первым проходом макета, чтобы иметь те же границы прокрутки, которые были до вращения. На этом этапе у разработчиков обычно возникают некоторые проблемы.
Ответ 6
Я нашел самый простой и совместимый с переходами способ:
@Override
public void onPause() {
super.onPause();
recyclerView.setLayoutFrozen(true);
}
@Override
public void onResume() {
super.onResume();
recyclerView.setLayoutFrozen(false);
}
Ответ 7
Вы можете использовать scrollToPosition
или smoothScrollToPosition
для прокрутки до любой позиции позиции в RecyclerView.
Если вы хотите перейти к позиции позиции в адаптере, вам придется использовать адаптер scrollToPosition
или smoothScrollToPosition
.