Android recyclerview get current position

Как сохранить позицию прокрутки RecyclerView с помощью RecyclerView.State?

У меня вопрос об Android RecyclerView.State .

Я использую RecyclerView, как я могу использовать и связать его с RecyclerView.State?

Моя цель — сохранить позицию прокрутки RecyclerView .

Как вы планируете сохранять последнюю сохраненную позицию с помощью RecyclerView.State ?

Вы всегда можете рассчитывать на хорошее состояние сохранения. Расширить RecyclerView и переопределить onSaveInstanceState () и onRestoreInstanceState() :

Обновить

Введено начиная с recyclerview:1.2.0-alpha02 релиза StateRestorationPolicy . Это мог бы быть лучший подход к данной проблеме.

Кроме того, @ rubén-viguera поделился более подробной информацией в ответе ниже. https://stackoverflow.com/a/61609823/892500

Старый ответ

Если вы используете LinearLayoutManager, он поставляется с предварительно созданным api сохранения linearLayoutManagerInstance.onSaveInstanceState () и восстановлением api linearLayoutManagerInstance.onRestoreInstanceState (. )

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

, и восстановить положение с сохраненным состоянием. например,

Подводя итог, ваш окончательный код будет выглядеть примерно так:

Изменить: вы также можете использовать тот же API с GridLayoutManager, так как это подкласс LinearLayoutManager. Спасибо @wegsehen за предложение.

Изменить: помните, что если вы также загружаете данные в фоновом потоке, вам понадобится вызов onRestoreInstanceState в вашем методе onPostExecute / onLoadFinished для восстановления позиции при изменении ориентации, например

и если это не сработает, попробуйте

Положить в магазин onPause() и восстановить в onResume()

Я хотел сохранить позицию прокрутки Recycler View, когда уходил от своей активности в списке, а затем нажимал кнопку «Назад», чтобы вернуться назад. Многие решения этой проблемы были либо намного сложнее, чем требовалось, либо не работали для моей конфигурации, поэтому я решил поделиться своим решением.

Сначала сохраните состояние вашего экземпляра в onPause, как многие показали. Думаю, здесь стоит подчеркнуть, что эта версия onSaveInstanceState является методом из класса RecyclerView.LayoutManager.

Ключ к правильной работе — это убедиться, что вы вызываете onRestoreInstanceState после присоединения адаптера, как некоторые указывали в других потоках. Однако фактический вызов метода намного проще, чем многие указывали.

Я устанавливаю переменные в onCreate (), сохраняю позицию прокрутки в onPause () и устанавливаю позицию прокрутки в onResume ()

Вам больше не нужно сохранять и восстанавливать состояние самостоятельно. Если вы установите уникальный идентификатор в xml и recyclerView.setSaveEnabled (true) (true по умолчанию), система автоматически сделает это. Подробнее об этом: http://trickyandroid.com/saving-android-view-state-correctly/

Все менеджеры компоновки, входящие в состав библиотеки поддержки, уже знают, как сохранять и восстанавливать положение прокрутки.

Положение прокрутки восстанавливается при первом проходе макета, что происходит при соблюдении следующих условий:

  • менеджер по расположению прикреплен к RecyclerView
  • адаптер прилагается к RecyclerView

Обычно вы устанавливаете диспетчер компоновки в XML, поэтому все, что вам нужно сделать сейчас, это

  1. Загрузите адаптер с данными
  2. Затем прикрепите адаптер к RecyclerView

Вы можете сделать это в любое время, это не ограничено Fragment.onCreateView или Activity.onCreate .

Пример: убедитесь, что адаптер подключен каждый раз при обновлении данных.

Сохраненная позиция прокрутки рассчитывается на основе следующих данных:

  • Положение адаптера первого элемента на экране
  • Пиксельное смещение верха элемента от верха списка (для вертикального расположения)

Поэтому вы можете ожидать небольшого несоответствия, например, если ваши элементы имеют разные размеры в портретной и альбомной ориентации.

RecyclerView / ScrollView / Что нужно иметь android:id для своего государства , чтобы спастись.

Читайте также:  Microsd как внутренняя память android

Вот мой подход к их сохранению и поддержанию состояния recyclerview во фрагменте. Сначала добавьте изменения конфигурации в родительскую активность, как показано ниже.

Затем в своем фрагменте объявите этот метод экземпляра

Добавьте ниже код в свой метод @onPause

Добавьте метод onConfigartionChanged, как показано ниже.

Этот подход решит вашу проблему. если у вас другой менеджер компоновки, просто замените верхний менеджер компоновки.

Вот как я восстанавливаю позицию RecyclerView с помощью GridLayoutManager после вращения, когда вам нужно перезагрузить данные из Интернета с помощью AsyncTaskLoader.

Сделайте глобальную переменную Parcelable и GridLayoutManager и статическую финальную строку:

Сохранение состояния gridLayoutManager в onSaveInstance ()

Восстановить в onRestoreInstanceState

Затем, когда загрузчик извлекает данные из Интернета, вы восстанавливаете позицию recyclerview в onLoadFinished ()

.. конечно, вам нужно создать экземпляр gridLayoutManager внутри onCreate. Ура

У меня было такое же требование, но решения здесь не совсем помогли мне перейти линию из-за источника данных для recyclerView.

Я извлекал состояние LinearLayoutManager RecyclerViews в onPause ()

Parcelable state сохраняется onSaveInstanceState(Bundle outState) и снова извлекается onCreate(Bundle savedInstanceState) , когда savedInstanceState != null .

Однако адаптер recyclerView заполняется и обновляется объектом ViewModel LiveData, возвращаемым вызовом DAO в базу данных Room.

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

Я подозреваю, что это связано либо с тем, что LinearLayoutManager состояние, которое я восстановил, было перезаписано, когда данные были возвращены вызовом базы данных, либо восстановленное состояние было бессмысленным для «пустого» LinearLayoutManager.

Если данные адаптера доступны напрямую (т. Е. Не связаны с вызовом базы данных), то восстановление состояния экземпляра в LinearLayoutManager может быть выполнено после того, как адаптер установлен в recyclerView.

Различие между двумя сценариями удерживало меня целую вечность.

На уровне 28 Android API я просто проверяю, что настроил свой метод LinearLayoutManager and RecyclerView.Adapter in my Fragment#onCreateView , и все работает Just Worked ™ ️. Мне не нужно было ничего делать onSaveInstanceState или onRestoreInstanceState работать.

Ответ Евгения Печанека объясняет, почему это работает.

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

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

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

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

Для меня проблема заключалась в том, что я каждый раз настраивал новый менеджер компоновки при смене адаптера, теряя позицию прокрутки очереди в recyclerView.

Я просто хотел бы поделиться недавней проблемой, с которой я столкнулся с RecyclerView. Я надеюсь, что любой, кто сталкивается с такой же проблемой, выиграет.

Требования к моему проекту: Итак, у меня есть RecyclerView, в котором перечислены некоторые интерактивные элементы в моем основном действии (Activity-A). При щелчке по элементу отображается новое действие с подробностями об элементе (действие-B).

Я реализовал в файле манифеста то, что Activity-A является родительским для Activity-B, таким образом, у меня есть кнопка возврата или возврата на панель действий Activity-B.

Читайте также:  Android new activity kotlin

Проблема: каждый раз, когда я нажимал кнопку «Назад» или «Домой» на панели действий Activity-B, Activity-A переходит в полный жизненный цикл действия, начиная с onCreate ().

Несмотря на то, что я реализовал onSaveInstanceState (), сохраняющий список адаптера RecyclerView, когда Activity-A запускает его жизненный цикл, saveInstanceState всегда имеет значение null в методе onCreate ().

Продолжая копаться в Интернете, я столкнулся с той же проблемой, но человек заметил, что кнопка «Назад» или «Домой» под устройством Anroid (кнопка «Назад / Домой по умолчанию») Activity-A не входит в жизненный цикл активности.

    Я удалил тег для родительской активности в манифесте для Activity-B

Я включил кнопку «Домой» или «Назад» на Activity-B

В методе onCreate () добавьте эту строку supportActionBar? .SetDisplayHomeAsUpEnabled (true)

В методе overide fun onOptionsItemSelected () я проверил item.ItemId, по которому щелкают элемент, на основе идентификатора. Идентификатор кнопки возврата:

android.R.id.home

Затем реализуйте вызов функции finish () внутри android.R.id.home

Это завершит Activity-B и принесет Acitivy-A без прохождения всего жизненного цикла.

Для моих требований это пока лучшее решение.

Источник

Простой пример Android RecyclerView

Я несколько раз составлял список элементов с помощью Android RecyclerView , но это довольно сложный процесс. Я просматриваю одно из многочисленных онлайн-руководств ( это , это и это хорошо), но я ищу простой пример, который я могу скопировать и вставить, чтобы быстро приступить к работе. Необходимы только следующие функции:

  • Вертикальная планировка
  • Один TextView в каждой строке
  • Реагирует на события щелчка

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

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

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

  • Добавить зависимости в gradle
  • Добавьте файлы макета xml для действия и для строки RecyclerView
  • Сделайте адаптер RecyclerView
  • Инициализируйте RecyclerView в своей деятельности

Обновить зависимости Gradle

Убедитесь, что в вашем gradle.build файле приложения есть следующие зависимости :

Вы можете обновить номера версий до самых последних . Используйте, compile а не, implementation если вы все еще используете Android Studio 2.x.

Создать макет занятия

Добавьте в RecyclerView свой xml-макет.

Создать макет строки

У каждой строки в нашем RecyclerView будет только один TextView . Создайте новый файл ресурсов макета.

Создайте адаптер

RecyclerView Нужен адаптер для заполнения представлений в каждой строке с данными. Создайте новый файл java.

  • Хотя это и не является строго необходимым, я включил функцию прослушивания событий щелчка по строкам. Это было доступно в старом ListViews и является обычной потребностью. Вы можете удалить этот код, если он вам не нужен.

Инициализировать RecyclerView в действии

Добавьте следующий код к своему основному действию.

  • Обратите внимание, что действие реализует то, ItemClickListener что мы определили в нашем адаптере. Это позволяет нам обрабатывать события щелчка по строке в onItemClick .

Законченный

Вот и все. Теперь вы сможете запустить свой проект и получить что-то похожее на изображение вверху.

Продолжается

Добавление разделителя между строками

Вы можете добавить такой простой разделитель

Если вы хотите что-то посложнее, см. Следующие ответы:

Изменение цвета строки при нажатии

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

Обновление строк

См. Этот ответ, чтобы узнать, как добавлять, удалять и обновлять строки.

дальнейшее чтение

Минимальное представление Recycler, готовое к использованию шаблона Kotlin для:

  • Вертикальная планировка
  • Один TextView в каждой строке
  • Реагирует на события щелчка (одиночное и долгое нажатие)
Читайте также:  Adobe sketch для android

Я знаю, что это старая ветка, и здесь есть ответы. Добавляем этот ответ для использования в будущем:

Добавьте вид корзины в свой макет

Создайте макет для отображения элементов списка (list_item.xml)

Теперь создайте минимальный адаптер для хранения данных, код здесь не требует пояснений.

Добавьте этот класс для обработки событий одиночного и длительного щелчка по элементам списка

Наконец, установите свой адаптер в режим Recycler View и добавьте Touch Listener, чтобы начать перехват события касания для одиночного или двойного нажатия на элементы списка.

Бонус; Обновить данные

Это будет самый простой вариант реализации RecyclerView.

activity_main.xml

list_item_view.xml

CustomAdapter.java

MainActivity.java

Начните с добавления библиотеки recyclerview.

Создайте класс модели.

создать класс адаптера.

создать макет row_uses.xml

Найдите recyclerview и заполните данные.

найти полное руководство и исходный код здесь:

На основе разных источников я создал простую реализацию RecyclerView с использованием простой библиотеки.

Добавьте эту строку в build.gradle

Добавить Создайте RecyclerView, добавив MyRecyclerView в activity_main.xml с помощью

Теперь в MainActivity создайте ViewHolder, передав имя класса, который необходимо привязать

Создайте переменную списка элементов и адаптеры с очень небольшим количеством строк, передав элементы, класс и макет в адаптер

ClickListener можно добавить следующими строками

Больше примеров и реализации можно найти здесь . Надеюсь это поможет .

Теперь вам нужен 1 адаптер на все RecyclerView

  • Один адаптер можно использовать для всех RecyclerView. Так что НЕТ onBindViewHolder , никакой onCreateViewHolder обработки.
  • Нет кода для настройки адаптера из класса Java / Kotlin. Проверить образец класса .
  • Вы можете установить события и пользовательские данные для каждого списка с помощью адаптеров привязки .

Я показываю здесь установку двух разных RecyclerView по 1 адаптеру —

activity_home.xml

Вы можете увидеть список передач, идентификатор макета элемента и прослушиватель щелчков из макета.

Эти настраиваемые атрибуты создаются BindingAdapter .

Теперь из Activity вы передаете список, нажимаете слушателя, например

HomeActivity.java

Вы не хотите слишком много читать, напрямую клонируйте / загружайте полный пример из моего репозитория github. И попробуйте сами.

Вы можете увидеть GeneralAdapter.java в репо выше.

Если у вас возникли проблемы при настройке привязки данных, см. Этот ответ .

Поскольку я пока не могу комментировать, я опубликую ссылку в качестве ответа. Я нашел простой, хорошо организованный учебник по recyclerview http://www.androiddeft.com/2017/10/01/recyclerview-android/

Кроме того, когда вы собираетесь добавить представление ресайклера в свою деятельность, вы хотите сделать, как показано ниже, и как вы должны это делать, было описано по ссылке

  • добавить компонент RecyclerView в файл макета
  • создать класс, который вы собираетесь отображать в виде строк списка
  • создать файл макета, который является макетом строки вашего списка
  • теперь нам нужен специальный адаптер, поэтому создайте собственный адаптер, расширив родительский класс RecyclerView.Adapter
  • добавьте recyclerview в свой mainActivity oncreate
  • добавление разделителей
  • добавление слушателей Touch

Вы можете использовать абстрактный адаптер с утилитами diff и фильтром

SimpleAbstractAdapter.kt

И расширить абстрактный адаптер с помощью методов реализации

ЗадачиAdapter.kt

добавить собственный фильтр

Вот гораздо более новое решение Kotlin для этого, которое намного проще, чем многие из написанных здесь ответов, оно использует анонимный класс.

Я взял на себя смелость использовать android.R.layout.simple_list_item_1, так как это проще. Я хотел еще больше упростить его и поместить ItemHolder в качестве внутреннего класса, но не мог понять, как ссылаться на него в типе во внешнем параметре класса.

реализация androidx.recyclerview: recyclerview: . Рекомендуется обновить библиотеки androidx, которые находятся здесь:

Затем необходимо обновить XML-тег Widget файла макета до: androidx.recyclerview.widget.RecyclerView

Зависимости

Один класс для элемента Click

Второй класс RecyclerView

Класс адаптера для элемента вторичной переработки

Источник

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