Создание кругового 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
, чтобы вы могли принять более обоснованное решение. Сообщите мне в комментариях, есть ли другие способы достижения этого.