Создание кругового RecyclerView в приложении для Android

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

Многие приложения реализуют такое поведение на своих наиболее заметных страницах:

Я пытался реализовать это, используя две стратегии:

  • Бесконечные предметы
  • Пользовательский прослушиватель прокрутки

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

Установление базовой линии

Сначала я реализую обычный RecyclerView с тремя элементами. Каждый элемент отображается в виде изображения. Это поможет нам сравнить, насколько эффективны циклические реализации по сравнению с этой базовой линией:

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

Это соответствует ожидаемому: три ImageViews с тремя Bitmaps в значительной степени подводят итог в нормальной реализации.

Реализация 1 - Бесконечные предметы

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

Это очень простая реализация, в которой Int.MAX_VALUE возвращается из getItemCount() метода RecycleViewAdapter:

Похоже, что большая часть ассигнований увеличилась вдвое, за исключением BitmapDrawable по сравнению с базовым уровнем. В этом случае после нескольких прокруток он увеличился до 278 распределений. Это может быть поводом для беспокойства в тех случаях, когда память - роскошь.

Преимущество этой реализации - ее абсолютная простота.

Примечание. Если вы хотите, чтобы RecyclerView мог прокручиваться в обоих направлениях с самого начала, тогда необходимо установить начальное положение RecyclerView. Это поместит равное количество элементов до и после первого элемента в фокусе.

recycler.scrollToPosition((Int.MAX_VALUE/2)-(Int.MAX_VALUE/2)%noOfItems)

Реализация 2 - Пользовательский прослушиватель прокрутки

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

В этой реализации из getItemCount() адаптера возвращается удвоенное количество элементов:

Помимо этого, нам нужно прикрепить пользовательский OnScrollListener к RecyclerView. В этом прослушивателе прокрутки всякий раз, когда мы понимаем, что находимся в конце RecyclerView, мы молча прокручиваем его до первой позиции. Слушатель прокрутки прикреплен к RecyclerView с помощью recyclerView.addOnScrollListener(CircularScrollListener()):

За исключением ImageViews, все остальные выделения Bitmaps эквивалентны некруговой реализации - и это преимущество достигается за счет сложности.

Однако есть несколько предостережений, связанных с этой реализацией, но их обработка довольно проста:

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

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

Заключение

Я попытался объяснить подробный анализ, который мы провели, чтобы выбрать лучший и наиболее эффективный метод реализации циркуляра RecyclerView, чтобы вы могли принять более обоснованное решение. Сообщите мне в комментариях, есть ли другие способы достижения этого.