Подтвердить что ты не робот

Как сохранить положение прокрутки 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, но он вообще не прокручивается.

4b9b3361

Ответ 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 вещи, которые нужно сделать, чтобы убедиться, что все будет работать нормально:

  1. Установите идентификатор для вашего прокручиваемого представления, что, вероятно, уже сделано. В противном случае Android не сможет автоматически сохранять состояние просмотра.

  2. Предоставьте данные перед первым проходом макета, чтобы иметь те же границы прокрутки, которые были до вращения. На этом этапе у разработчиков обычно возникают некоторые проблемы.

Ответ 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.