Save scroll position android

How to Save and Restore the Scroll Position and State of a Android ListView

Moonshoot

Moonshoot is a
Student Feature.

If you are developing an Android app, you probably ran into Android ListViews. ListViews are a very capable, but also sometimes a challenging component. As an active Android user I see a common problem in many Android apps: they lose the scroll progress I made on a ListView after returning from a different view or restarting the app. Some apps at least restore the ListView to the general area, but not pixel-perfect. In this guide, I will outline three different approaches.

Two Possible but Flawed Solutions

If you research the issue, most guides will tell you to figure out the position of the first item, which is visible on the ListView with listView.getFirstVisiblePosition(); . I will not post the entire code here, since it has a major drawback: it is inaccurate. A ListView item, which is only partially visible at the top, will be ignored. When restoring the ListView using the first visible position, the ListView will usually make a small jump up. Slightly irritating and confusing for the user.

Thus, some suggest to calculate the distance of the first ListView item to the top and then save the value in combination with getFirstVisiblePosition() . While this might lead to the desired result, it is neither the Android-way of doing things, nor nice and clean code.

The Final and Optimal Solution

The best solution is to use the pre-defined implementation, which unfortenately is not very established in the Android community. Once again, the best answer is buried on StackOverflow and not even marked as correct solution. The code to save the ListView state:

The code to restore the ListView state, including scroll position:

You can use these two snippets to correctly manage ListViews throughout the activity or fragment lifecycle. Additionally, if you need to set a new adapter, you can hold on to the scroll position:

I hope you can use this little guide to improve the user experience of your app. You can always find us on twitter for feedback and questions: @futurestud_io.

Get Notified on New Future Studio
Content and Platform Updates

Get your weekly push notification about new and trending
Future Studio content and recent platform enhancements

Источник

Restore RecyclerView scroll position

You might have had the problem where a RecyclerView loses the scroll position when your Activity / Fragment is re-created. This usually happens because the Adapter data is loaded asynchronously and data hasn’t loaded by the time RecyclerView needs to layout so it fails to restore the scroll position.

Starting with 1.2.0-alpha02 , RecyclerView offers a new API to let the Adapter block layout restoration until it is ready. Read on to learn how to use this new API and how it works.

Restoring the scroll position

There are several ways to ensure a correct scroll position that you might have adopted. The best one is making sure that you always set the data on the Adapter before the first layout pass by caching the data you want to display in memory, in a ViewModel or in a repository. If this approach wasn’t possible, other solutions were either more complicated, like avoiding setting the Adapter on the RecyclerView , which can bring issues with items like headers, or misusing LayoutManager.onRestoreInstanceState API.

Читайте также:  Что такое sdn контакты android

The recyclerview:1.2.0-alpha02 solution is a new Adapter method which allows you to set a state restoration policy (via the StateRestorationPolicy enum). This has 3 options:

  • ALLOW — the default state, that restores the RecyclerView state immediately, in the next layout pass
  • PREVENT_WHEN_EMPTY — restores the RecyclerView state only when the adapter is not empty ( adapter.getItemCount() > 0 ). If your data is loaded async, the RecyclerView waits until data is loaded and only then the state is restored. If you have default items, like headers or load progress indicators as part of your Adapter , then you should use the PREVENT option, unless the default items are added using ConcatAdapter (find out more here). ConcatAdapter waits for all of its adapters to be ready and only then it restores the state.
  • PREVENT — all state restoration is deferred until you set ALLOW or PREVENT_WHEN_EMPTY .

Set the state restoration policy on the adapter like this:

That’s it! A short and sweet post to get you up to date with RecyclerView ’s lazy state restoration feature. Start using it 🏁👩‍💻👨‍💻!

Источник

Saving Scroll Positions of Nested RecyclerViews

May 3, 2019 · 2 min read

One of the most annoying things when using RecyclerViews is that by nature they don’t store item states upon recycling. Thus, each item resets to its original state from creation as soon as you scroll away from the view. And the issue with nested RecyclerView carousels is that each carousel loses the index that was scrolled to originally. Makes you wonder, is there a trend being practiced in over-the-top apps like Netflix, Prime Video, Disney+, or even Google Play Store? The answer is yes.

The idea behind t his solution is that we will save the current scroll index of each horizontal carousel in some data structure before it is recycled. This way when the views return to foreground we can retrieve the saved indices and set the scroll positions for the carousels.

Few things to consider:

  • All changes should be done in the outer adapter.
  • We should store a LinearLayoutManager in the view holder and instantiate it upon creating its inner RecyclerView.
  • Fun fact: you can get the parent context in an adapter without passing it to the constructor inside onCreateViewHolder with mContext = viewGroup.getContext()
  • Create a SparseIntArray or map to hold the scroll position of each carousel.

Now override the onViewRecycled to store the position of the first visible item in that carousel after the view holder recycles.

Now that the states are stored we can retrieve them dynamically in onBindViewHolder per position.

We have now just created an adapter that maintains the states of a carousel when it is recycled through the list! Although this solution works best when SnapHelper is used for the carousel, since the positions closest to the first visible item is used as a reference point. This technique can be used to store and retrieve data and complex views with similar list patterns.

Читайте также:  Телевизор мистери пульт андроид

Источник

Как сохранить положение прокрутки RecyclerView в Android?

У меня есть вид Recycler, который лежит внутри SwipeRefreshLayout. Кроме того, есть возможность открывать каждый элемент в другом действии. После возвращения обратно в Recycler мне нужно прокрутить выбранный элемент или предыдущий Y. Как это сделать?

Да, я googled, нашел статьи в StackOverFlow о сохранении экземпляра менеджера макета, как этот: RecyclerView хранить/восстанавливать состояние между действиями. Но мне это не помогает.

UPDATE

Сейчас у меня такая разрешающая проблема, но, конечно, она также не работает.

Да, я попробовал scrollTo (int, int) — doen’t work.

Теперь я попробовал просто прокрутить, например, до Y = 100, но он вообще не прокручивается.

ОТВЕТЫ

Ответ 1

Сохранить текущее состояние позиции возврата в цикл @onPause:

Восстановите положение прокрутки @onResume:

или другим способом может быть @onPause:

Ответ 2

Многие из этих ответов, похоже, усложняют его.

LayoutManager поддерживает onRestoreInstanceState из коробки, поэтому нет необходимости сохранять позиции прокрутки и т.д. Встроенный метод уже сохраняет идеальные позиции пикселей.

Пример кода фрагмента (нулевая проверка и т.д. удалена для ясности):

тогда просто вызовите

как только ваши данные будут привязаны к вашему RecyclerView

Ответ 3

Пользователь вашего ресайклера viewlinelayoutmanager для получения положения прокрутки

и при восстановлении используйте следующий код

Надеюсь, это поможет вам

Ответ 4

чтобы сохранить позицию в настройках, добавьте это в свой onStop()

затем восстановить положение, как это

последний код должен быть добавлен в событие Адаптера (не уверен, что это событие ведьмы, но в моем случае это onEvent() — com.google.firebase.firestore.EventListener)

Ответ 5

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

Возьмите текущую позицию прокрутки и сохраните ее в Activitys onSaveInstanceState Расширение определенного прокручиваемого представления, чтобы сделать то же самое там. Предотвращение разрушения Activity при вращении И да, они работают нормально, но…

Но на самом деле все гораздо проще, потому что Android уже делает это за вас!

Если вы внимательно посмотрите на источники RecyclerView/ListView/ScrollView/NestedScrollView, вы увидите, что каждый из них сохраняет свою позицию прокрутки в onSaveInstanceState. И во время первого прохода макета они пытаются прокрутить до этой позиции в методе onLayout.

Есть только 2 вещи, которые нужно сделать, чтобы убедиться, что все будет работать нормально:

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

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

Ответ 6

Я нашел самый простой и совместимый с переходами способ:

Ответ 7

Вы можете использовать scrollToPosition или smoothScrollToPosition для прокрутки до любой позиции позиции в RecyclerView.

Если вы хотите перейти к позиции позиции в адаптере, вам придется использовать адаптер scrollToPosition или smoothScrollToPosition .

Источник

Как сохранить позицию прокрутки RecyclerView в Android?

У меня есть представление Recycler, которое находится внутри SwipeRefreshLayout. Кроме того, у вас есть возможность открывать каждый элемент в другом действии. После возврата в Recycler мне нужно прокрутить до выбранного элемента или до предыдущего Y. Как это сделать?

Да, я погуглил, нашел в StackOverFlow статьи о сохранении экземпляра диспетчера компоновки, например этот: RecyclerView сохраняет / восстанавливает состояние между действиями. Но мне это не помогает.

Читайте также:  Защита рабочего стола от изменений android

ОБНОВЛЕНИЕ

Сейчас у меня есть такая решающая проблема, но, конечно, тоже не работает.

Да, я пробовал scrollTo (int, int) — не работает.

Теперь я попробовал просто прокрутить, например, до Y = 100, но прокрутки нет вообще.

8 ответов

Сохраните текущее состояние позиции повторного просмотра @onPause:

Восстановить позицию прокрутки @onResume:

Или другим способом может быть @onPause:

По какой-то причине существует множество вводящих в заблуждение советов / предложений о том, как сохранять и восстанавливать положение прокрутки в your_scrolling_container при изменении ориентации.

Взять текущую позицию прокрутки и сохранить ее в onSaveInstanceState Activity. Расширение определенного прокручиваемого View, чтобы сделать то же самое. Предотвращение разрушения Activity при вращении. И да, они работают нормально, но .

Но на самом деле все намного проще, потому что Android уже делает это за вас!

Если вы внимательно посмотрите на источники RecyclerView / ListView / ScrollView / NestedScrollView, вы увидите, что каждый из них сохраняет свою позицию прокрутки в onSaveInstanceState. И во время первого прохода макета они пытаются прокрутить до этой позиции в методе onLayout.

Чтобы убедиться, что все работает нормально, вам нужно сделать всего 2 вещи:

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

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

Самый простой и совместимый с переходом способ, который я нашел:

Используйте свой ресайклер для просмотра linearlayoutmanager для получения позиции прокрутки

И при восстановлении используйте следующий код

Надеюсь, это поможет тебе

Вы можете использовать scrollToPosition или smoothScrollToPosition для перехода к любой позиции элемента в RecyclerView .

Если вы хотите прокрутить до позиции элемента в адаптере , вам придется использовать адаптер scrollToPosition или smoothScrollToPosition .

Чтобы сохранить позицию в настройках, добавьте это в свой onStop ()

Затем восстановите положение, подобное этому

Этот последний код должен быть добавлен внутри события адаптера (не уверен, что событие ведьмы, но в моем случае было onEvent () — com.google.firebase.firestore.EventListener)

Начиная с версии 1.2.0-alpha02 библиотеки androidx recyclerView, она теперь управляется автоматически. Просто добавьте его с помощью:

Перечисление StateRestorationPolicy имеет 3 варианта:

  • РАЗРЕШИТЬ — состояние по умолчанию, которое немедленно восстанавливает состояние RecyclerView на следующем проходе макета
  • PREVENT_WHEN_EMPTY — восстанавливает состояние RecyclerView только тогда, когда адаптер не пустой (adapter.getItemCount () & gt; 0). Если ваши данные загружаются асинхронно, RecyclerView ждет, пока данные будут загружены, и только после этого состояние восстанавливается. Если у вас есть элементы по умолчанию, такие как заголовки или индикаторы выполнения загрузки, как часть вашего адаптера, вам следует использовать параметр PREVENT, если элементы по умолчанию не добавлены с помощью MergeAdapter. MergeAdapter ожидает готовности всех своих адаптеров и только после этого восстанавливает состояние.
  • PREVENT — все восстановление состояния откладывается до тех пор, пока вы не установите ALLOW или PREVENT_WHEN_EMPTY.

Обратите внимание, что на момент этого ответа библиотека recyclerView все еще находится в альфа03, но альфа-фаза не подходит для производственных целей .

Многие из этих ответов, кажется, слишком усложняют его.

LayoutManager поддерживает onRestoreInstanceState из коробки, поэтому нет необходимости сохранять позиции прокрутки и т. Д. Встроенный метод уже сохраняет идеальные позиции пикселей.

Пример кода фрагмента (нулевая проверка и т. д. удалена для ясности):

Тогда просто позвони

Как только ваши данные будут повторно прикреплены к вашему RecyclerView

Источник

Оцените статью