- RecyclerView
- getItemCount()
- onCreateViewHolder
- onBindViewHolder()
- Горизонтальная прокрутка
- Оптимизация
- Как создать горизонтальный ListView с RecyclerView?
- RecyclerView горизонтальная прокрутка в центре
- Создание сложного RecyclerView за 20 минут в Android на базе Groupie
- Создание проекта и добавление библиотек.
- Создание ячеек для отображения контента
- Создание главной ячейки с вложенным RecyclerView
- Ячейка для фильма
- Квадратная ячейка для отображения обложки игры
- Все вместе. Соединяем все ячейки вместе
RecyclerView
Компонент RecyclerView появился в Android 5.0 Lollipop и находится в разделе Containers. Для простоты буду называть его списком, хотя на самом деле это универсальный элемент управления с большими возможностями.
Раньше для отображения прокручиваемого списка использовался ListView. Со временем у него обнаружилось множество недостатков, которые было трудно исправить. Тогда решили создать новый элемент с нуля.
Вначале это был сырой продукт, потом его доработали. На данном этапе можно считать, что он стал полноценной заменой устаревшего ListView.
Схематично работу RecyclerView можно представить следующим образом. На экране отображаются видимые элементы списка. Когда при прокрутке списка верхний элемент уходит за пределы экрана и становится невидимым, его содержимое очищается. При этом сам «чистый» элемент помещается вниз экрана и заполняется новыми данными, иными словами переиспользуется, отсюда название Recycle.
Компонент RecyclerView не является родственником ListView и относится к семейству ViewGroup. Он часто используется как замена ListView, но его возможности шире.
Следует сказать, что при работе с ним приходится писать много кода, который пугает новичков. Если с RecyclerView работать не постоянно, то порой забываются детали и сложно вспомнить необходимые шаги. Многие просто сохраняют отдельные шаблоны и копируют в разные проекты.
Внешний вид можно представить не только в виде обычного списка, но и в виде сетки. При необходимости можно быстро переключиться между разными типами отображения.
Для размещения своих дочерних элементов используется специальный менеджер макетов LayoutManager. Он может быть трёх видов.
- LinearLayoutManager — дочерние элементы размещаются вертикально (как в ListView) или горизонтально
- GridLayoutManager — дочерние элементы размещаются в сетке, как в GridView
- StaggeredGridLayoutManager — неравномерная сетка
Можно создать собственный менеджер на основе RecyclerView.LayoutManager.
RecyclerView.ItemDecoration позволяет работать с дочерними элементами: отступы, внешний вид.
ItemAnimator — отвечает за анимацию элементов при добавлении, удалении и других операций.
RecyclerView.Adapter связывает данные с компонентом и отслеживает изменения.
- notifyItemInserted(), notifyItemRemoved(), notifyItemChanged() — методы, отслеживающие добавление, удаление или изменение позиции одного элемента
- notifyItemRangeInserted(), notifyItemRangeRemoved(), notifyItemRangeChanged() — методы, отслеживающие изменение порядка элеметов
Стандартный метод notifyDataSetChanged() поддерживается, но он не приводит к внешнему изменению элементов на экране.
Программисты со стажем знают, что для создания «правильного» ListView нужно было создавать класс ViewHolder. В старых списках его можно было игнорировать. Теперь это стало необходимым условием.
Общая модель работы компонента.
Мы рассмотрим только базовый пример для быстрого знакомства. В реальных проектах примеры будут гораздо сложнее, чтобы обеспечить другие функциональные возможности — обработка жестов, анимация, динамическое удаление и добавление элементов.
Размещаем компонент в макете экрана через панель инструментов. Но сначала добавим зависимость.
Создадим макет для отдельного элемента списка. Варианты могут быть самыми разными — можно использовать один TextView для отображения строк (имена котов), можно использовать связку ImageView и TextView (имена котов и их наглые морды). Мы возьмём для примера две текстовые метки. Создадим новый файл res/layout/recyclerview_item.xml.
Добавим компонент в разметку экрана активности.
Минимальный код для запуска.
Пока ничего сложного, но выводить такой список ничего не будет. Нужен адаптер и данные для отображения. В адаптере описывается способ связи между данными и компонентом.
Начнём по порядку, чтобы запомнить последовательность. Для начала создадим обычный класс и в конструкторе передадим список строк. Список будет содержать имена котов.
Класс MyViewHolder на основе ViewHolder служит для оптимизации ресурсов. Новый класс добавим в состав нашего созданного ранее класса.
В созданном классе нужно просто перечислить используемые компоненты из макета для отдельного элемента списка. В нашем примере задействованы два TextView, инициализируем их через идентификаторы.
Создадим адаптер — наследуем наш класс от класса RecyclerView.Adapter и в качестве параметра указываем созданный нами MyViewHolder. Студия попросит реализовать три метода.
getItemCount()
Как правило данные являются однотипными, например, список или массив строк. Адаптеру нужно знать, сколько элементов нужно предоставить компоненту, чтобы распределить ресурсы и подготовиться к отображению на экране. При работе с коллекциями или массивом мы можем просто вычислить его длину и передать это значение методу адаптера getItemCount(). В простых случаях мы можем записать код в одну строчку.
onCreateViewHolder
В методе onCreateViewHolder нужно указать идентификатор макета для отдельного элемента списка, созданный нами ранее в файле recyclerview_item.xml. А также вернуть наш объект класса ViewHolder.
onBindViewHolder()
В методе адаптера onBindViewHolder() связываем используемые текстовые метки с данными — в одном случае это значения из списка, во втором используется одна и та же строка.
Должно получиться следующее.
Подключаем в активности. Создадим пока бессмысленный список строк, который передадим в адаптер.
Запускаем ещё раз.
Вариант с числами нам не интересен, поэтому добавим котов. Имена котов и кошек разместим в ресурсах в виде массива в файле res/values/strings.xml.
Создадим новую функцию для получения списка котов из ресурсов и передадим его адаптеру.
Горизонтальная прокрутка
Можем указать горизонтальный вариант прокрутки. Остальной код менять не придётся.
А можно вообще обойтись только XML-декларацией.
Оптимизация
При прокрутке под капотом выполняется сложная работа по обновлению контента. Поэтому не следует перегружать элементы списка сложной структурой и не перебарщивайте с вложенными элементами, а также нужно следить за оптимизацией, чтобы избежать лагов.
При работе с изображениями старайтесь использовать готовые библиотеки Picasso, Glide, Fresco и т.д.
Если картинки загружаются с сервера, неплохо заранее вычислять их размеры и пропорции. В некоторых случаях желательно позаботиться, чтобы картинки были одного размера (если это возможно).
Не перегружайте лишним кодом метод onBindViewHolder(). Только самое необходимое.
Источник
Как создать горизонтальный ListView с RecyclerView?
Мне нужно реализовать горизонтальный список в приложении для Android. Я сделал несколько исследований и наткнулся. Как создать горизонтальный ListView в Android? И горизонтальный ListView в Android? Однако эти вопросы были заданы перед выпуском Recyclerview. Есть ли лучший способ реализовать это сейчас с Recyclerview?
Есть ли лучший способ реализовать это сейчас с Recyclerview?
Когда вы используете RecyclerView , вам нужно указать LayoutManager который отвечает за прокладку каждого элемента в представлении. LinearLayoutManager позволяет вам указать ориентацию, как и обычный LinearLayout .
Чтобы создать горизонтальный список с помощью RecyclerView , вы можете сделать что-то вроде этого:
Попытка построить горизонтальный ListView занимает слишком много времени. Я разрешил это двумя способами.
1. Используя ViewPager, адаптер которого простирается от PagerAdapter.
2. Используйте RecyclerView так же, как указано выше. Необходимо применить LayoutManager, как в следующем коде:
Если вы хотите использовать RecyclerView с GridLayoutManager, это способ достижения горизонтальной прокрутки.
Если вы хотите использовать Horizontal Recycler View, чтобы выступать в качестве ViewPager, тогда это возможно теперь с помощью LinearSnapHelper который добавляется в Support Library версии 24.2.0.
Сначала добавьте RecyclerView в свою активность / фрагмент
В моем случае я использовал CardView внутри RecyclerView
blog_row.xml
В вашей деятельности / фрагменте
Последний шаг – установить адаптер для RecyclerView
С выпуском библиотеки RecyclerView теперь вы можете легко совместить список изображений с текстом. Вы можете использовать LinearLayoutManager, чтобы указать направление, в котором вы хотели бы сориентировать свой список, вертикальный или горизонтальный, как показано ниже.
Вы можете загрузить полную рабочую демонстрацию из этой публикации
Существует подкласс RecyclerView с именем HorizontalGridView, который вы можете использовать для горизонтального направления. VerticalGridView для вертикального направления
Источник
RecyclerView горизонтальная прокрутка в центре
Я пытаюсь сделать вид с карусели здесь, используя RecyclerView, я хочу, чтобы элемент защелкнул середину экрана при прокрутке, по одному элементу за раз. Я пробовал использовать recyclerView.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING);
Но «просмотр по-прежнему прокручивается гладко, я также пытался реализовать свою собственную логику, используя прослушиватель прокрутки:
Теперь салфетка справа налево работает нормально, но не наоборот, что мне здесь не хватает?
С LinearSnapHelper это сейчас очень просто.
Все, что вам нужно сделать, это:
Обновить
Доступный с 25.1.0, PagerSnapHelper может помочь достичь эффекта ViewPager . Используйте его так же, как вы бы использовали LinearSnapHelper .
Старое обходное решение:
Если вы хотите, чтобы он был похож на ViewPager , попробуйте это вместо этого:
Выполнение выше просто возвращает позицию рядом с текущим элементом (в центре) в зависимости от направления скорости, независимо от величины.
Первый – это первое партийное решение, включенное в библиотеку поддержки 24.2.0. Это означает, что вы должны добавить это в build.gradle вашего модуля build.gradle или обновить его.
Важное обновление:
Google реализовал это в Android Support Library 24.2.0 (выпущен в августе 2016 года). В примечаниях к выпуску говорится следующее:
RecyclerView.OnFlingListener добавлен для поддержки пользовательского поведения в ответ на flings. Класс SnapHelper обеспечивает реализацию специально для привязки дочерних представлений, а класс LinearSnapHelper расширяет эту реализацию, чтобы обеспечить выравнивание по центру, похожее на ViewPager .
Заметьте, что я еще не пытался использовать LinearSnapHelper . Я все еще использую свое решение, которое отлично работает.
Оригинальный ответ:
После многих часов попыток ViewPager трех различных решений в SO я, наконец, создал решение, которое очень близко имитирует поведение, обнаруженное в ViewPager .
Решение основано на решении @eDizzle, которое, по моему мнению, я улучшило, чтобы сказать, что оно работает почти как ViewPager .
Вот как это выглядит:
Важно: ширина элемента RecyclerView точно такая же, как на экране. Я не пробовал с другими размерами. Также я использую его с горизонтальным LinearLayoutManager . Я думаю, что вам нужно будет адаптировать код, если вы хотите вертикальную прокрутку.
Здесь у вас есть код:
Вы должны использовать findFirstVisibleItemPosition для перехода в противоположном направлении. И для определения того, в каком направлении находился салфетка, вам нужно получить либо скорость движения, либо изменение x. Я подошел к этой проблеме немного под другим углом, чем у вас.
Создайте новый класс, который расширяет класс RecyclerView, а затем переопределяет метод Fling RecyclerView следующим образом:
Если цель состоит в том, чтобы заставить RecyclerView имитировать поведение ViewPager существует довольно простой подход
Используя PagerSnapHelper вы можете получить такое поведение, как ViewPager
Я передаю этот менеджер компоновки в RecycledView и устанавливаю смещение, необходимое для элементов центра. Все мои предметы имеют одинаковую ширину, поэтому постоянное смещение в порядке
Источник
Создание сложного RecyclerView за 20 минут в Android на базе Groupie
Списки являются основным способом представления различного контента в мобильных приложениях. Будь то социальная сеть, приложение для чтения книг или интернет-магазин, в большинстве таких приложений встречаются списки с разными видами ячеек, разного уровня вложенности.
Естественно, чтобы поддержать такое разнообразие контента и при этом сохранить оптимальную производительность для такой задачи лучше всего использовать RecyclerView. Как создать список, поддерживающий разные виды ячеек, которые в свою очередь могут тоже содержать вложенные списки за 20 минут, я покажу на примере в этой статье. В конце у вас получится вот такой список:
Итак, задача: создать список для отображения различного вида контента, при этом каждая категория, то есть ячейка списка может содержать неограниченное количество более мелких ячеек и иметь горизонтальный скрол. Звучит сложно? Если вы думаете что это сложная задача, над которой вам нужно будет работать всю неделю, то спешу вас обрадовать, мы сделаем такой список примерно на полчаса.
Подходов к решению такой задачи, множество, но суть решения одна — здесь необходимо использовать RecyclerView с различными типами ячеек, в которых также находится RecyclerView для возможности горизонтального скролла неограниченного количества ячеек. Можно использовать как стандартный подход, в котором необходимо будет создать adapter для каждого из списков, ViewHolders для разного типа ячеек и так далее. А можно использовать более быстрый подход без множества похожего кода на базе библиотеки Groupie
Groupie is a simple, flexible library for complex RecyclerView layouts.
Это простая и в тоже время мощная библиотека для упрощения построения списков на базе RecyclerView, которая заметно ускорит разработку сложных списков как в примерах выше.
Безусловно, все что мы видели можно сделать и без этой библиотеки, тем более совсем недавно в Android появился MergeAdapter, о котором я писал в этой статье. Но так или иначе вы столкнётесь с недостатками стандартного подхода, описанного в той же статье. Поэтому, сегодня мы попробуем новый подход, ускоряющий разработку, избавляющий от написания бойлерплейт-кода и соответсвующий принципам SOLID.
Если кратко, то алгоритм действий выглядит следующим:
- Создаём проект. Добавляем нужные зависимости.
- Определяем нужные ячейки. Создаём layouts для отображения UI
- Соединяем ячейки с адаптером RecyclerView и наслаждаемся результатом.
Создание проекта и добавление библиотек.
Для создания списка как в примере на картинке нам понадобится 4 библиотеки: RecyclerView, CardView, Picasso (для отображения картинок) и Groupie. Добавим всё это в build.gradle(app):
Кроме этого, добавьте в build.gradle в блок android
Нажмите Sync Now для скачивания необходимых зависимостей.
Создание ячеек для отображения контента
Для отображения списка нам понадобится 3 типа ячеек:
- Общая ячейка — контейнер для отображения вложенного списка. Обозначена красным прямоугольником.
- Ячейка внутри основной ячейки для отображения информации о фильме. Такие ячейки выделены синим прямоугольником. Они находятся внутри основной ячейки в RecyclerView c горизонтальным скролом.
- Квадратная ячейка для отображения обложек игр. Выделена зелёным цветом.
Создание главной ячейки с вложенным RecyclerView
Вначале создадим общую ячейку с вложенным RecyclerView для отображения более мелких ячеек.
Вёрстка такой ячейки будет состоять из CardView с LinearLayout для отображения названия, описания и RecyclerView для отображения внутренних ячеек.
Теперь создадим логику для отображения данных ячейки.
Каждая ячейка при использовании Groupie должна быть наследником от абстрактного класса Item. Для этого необходимо переопределить всего 2 метода getLayout() и bind(). То есть для создания ячейки вам нужно указать layout который будет использоваться для отображения UI и дописать логику формирования данных для этой ячейки и всё! Теперь не нужно писать однотипные адаптеры для разных ячеек или комбинировать множество разных типов ячеек в одном адаптере, нарушая принципы SOLID. Ну или выдумывать базовые классы для ячеек, только для того, чтобы можно было переиспользовать один и тот же адаптер. C Groupie для каждой ячейки вам необходимо создать свой класс, и описать в нем UI!
В данном пример мы будем использовать одну общую ячейку, которая на вход принимает название, описание и список других Item, то есть ячеек, которые и будут наполнять вложенный в эту ячейку RecyclerView. Самое интересное тут, пожалуй вот эта строчка:
То есть для RecyclerView который внутри этой ячейки, необходимо добавить общий GroupAdapter и наполнить его ячейками, которые являются наследниками Item.
Общий контейнер готов, теперь осталось сверстать частные ячейки для каждого типа контента. Их будет 2:
- Ячейка для фильма с названием фильма
- Квадратная ячейка с обложкой игры
Ячейка для фильма
Ячейка для фильма, также должна быть наследником Item и должна реализовать 2 метода:
Верстка достаточно простая и код можно посмотреть в проекте на GitHub.
Квадратная ячейка для отображения обложки игры
Эта ячейка тоже является достаточно простой, поэтому лучше посмотрите код проекта.
Все вместе. Соединяем все ячейки вместе
Для создания списка теперь нужно создать ячейки с контентом и передать их в адаптер RecyclerView. Для создания ячеек были созданы 2 метода getPopularMovies() и getPopularGames() которые возвращают ячейки типа Item.
Каждый из методов возвращает 1 ячейку MainCardContainer — которой передаётся в качестве аргумента список ячеек уже с контентом для вложенного RecyclerView. Например, для ячейки которая отображает список фильмов нужно указать список ячеек MovieItem. Для второй ячейки, которая отображает список игр — мы создадим также метод, который создаст основную общую ячейку и передаст ячейки с играми.
В итоге создание списка теперь будет выглядеть так:
Последняя строка как раз использует GroupAdapter в который мы можем передать любые ячейки, которые являются наследниками Item.
Ну вот и всё! Буквально за 30 минут мы создали сложный список для отображения различного типа контента с вложенным горизонтальным списком! Сравните такой подход с традиционным и сделайте выводы сами! Абсолютно точно такой подход сэкономит вам время на разработку подобных UI — компонентов и избавит от кучи бесполезного кода. Хотите узнать ещё больше продвинутых фишек? Успейте записаться на онлайн-интенсив по Android-разработке
Понравилась статья? Не забудь подписаться и поставить лайк, а ещё
Источник