Android studio recyclerview animation

Советы для профессионального использования RecyclerView. Часть 2

Продолжая предыдущую статью, в этой я расскажу про ItemDecoration и ItemAnimator и постараюсь объяснить принцип их работы в RecyclerView на примере простого приложения, которое доступно на Github.

1. ItemDecoration

ItemDecoration используется для декорирования элементов списка в RecyclerView .

С помощью ItemDecoration вы сможете добавлять разделители между view -компонентам, выравнивать их или разбивать равными промежутками. Чтобы добавить простой разделитель между view -компонентами, воспользуйтесь классом DividerItemDecoration , который можно найти в библиотеке поддержки версии 25.1.0 и выше. Следующий фрагмент кода демонстрирует его реализацию:

Лучший способ создания собственного разделителя — расширение класса RecyclerView.ItemDecoration . В примере приложения я использовал GridLayoutManager и применил CharacterItemDecoration к RecyclerView :

Здесь CharacterItemDecoration устанавливает смещение (англ. offset) на 50 пикселей в своём конструкторе и переопределяет getItemOffsets(. ) . Внутри метода getItemOffsets() каждое поле outRects определяет количество пикселей, которые необходимо установить для каждого view -компонента, подобно внутренним и внешним отступам. Поскольку я использовал GridLayoutManager и хотел настроить равные расстояния между элементами сетки, я установил отступ справа в 25 пикселей (т.е. offset/2) для каждого чётного элемента и отступ слева в 25 пикселей для каждого нечётного элемента, сохраняя при этом верхний отступ одинаковым для всех элементов.

2. ItemAnimator

ItemAnimator используется для анимации элементов или view -компонентов внутри RecyclerView .

Давайте сделаем наше приложение «Инстаграмоподобным», расширив DefaultItemAnimator и переопределив несколько методов.

Метод canReuseUpdatedViewHolder(. ) определяет, будет ли один и тот же ViewHolder использоваться для анимации, если данные этого элемента изменятся. Если он возвращает false , то оба ViewHolders — старый и обновленный — передаются в метод animateChange(. ) .

RecyclerView вызывает метод recordPreLayoutInformation(. ) до начала отрисовки layout . ItemAnimator должен записывать необходимую информацию о view -компоненте до того, как он будет перезаписан, перемещен или удалён. Данные, возвращаемые этим методом, будут переданы соответствующему методу анимации (в нашем случае это animateChange(. ) ).

RecyclerView вызывает метод animateChange(. ) , когда элемент адаптера присутствует одновременно до и после отрисовки после вызова метода notifyItemChanged(int) . Этот метод также можно использовать, при вызове notifyDataSetChanged() , если при этом в адаптере используются стабильные идентификаторы. Это необходимо для того, чтобы RecyclerView мог переиспользовать view -компоненты в тех же ViewHolders . Обратите внимание на то, что этот метод принимает в качестве аргументов: (ViewHolder oldHolder, ViewHolder newHolder, ItemHolderInfo preInfo, ItemHolderInfo postInfo). Поскольку мы повторно используем ViewHolder , оба — oldHolder и newHolder — одинаковы.

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

Это запускает всю цепочку вызовов: canReuseUpdatedViewHolder(. ) , recordPreLayoutInformation(. ) и, в конечном итоге, animateChange(. ) в ItemAnimator , который, в свою очередь, анимирует элемент списка и иконку сердечка в этом элементе (пример на гифке выше).

Это вторая часть серии статей про RecyclerView . Если пропустили первую часть, то читайте её здесь.

Ещё несколько хороших статей на тему RecyclerView :

Читайте также:  Что такое отключенная защита андроида

Источник

Анимации Android RecyclerView на Kotlin

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

Простого функционального кода недостаточно для красивого современного приложения. Думаю, все согласны с тем, что сегодня приложение должно обладать красивым дизайном и показывать переходы и анимации. Сегодня я попытаюсь объяснить один из этих аспектов, а именно анимации элементов RecyclerView в Android. Я буду использовать Android Studio и Kotlin. Наслаждайтесь 🙂

Начнем с основ

Прежде всего, вам нужно создать папку с анимацией для хранения файлов анимации.

res(right-click)->New->Android Resource Directory

» data-medium-file=»https://i0.wp.com/apptractor.ru/wp-content/uploads/2020/11/1-11.png?fit=612%2C113&ssl=1″ data-large-file=»https://i0.wp.com/apptractor.ru/wp-content/uploads/2020/11/1-11.png?fit=612%2C113&ssl=1″ svg+xml,%3Csvg%20xmlns=’http://www.w3.org/2000/svg’%20viewBox=’0%200%20612%20113’%3E%3C/svg%3E» alt=»Анимации Android RecyclerView на Kotlin» width=»612″ height=»113″ data-recalc-dims=»1″ data-lazy-src=»https://i0.wp.com/apptractor.ru/wp-content/uploads/2020/11/1-11.png?resize=612%2C113&ssl=1″/>

res(right-click)->New->Android Resource Directory

После этого щелкните правой кнопкой мыши папку с анимацией и создайте «Animation Resources File».

Анимации Android RecyclerView: объяснение свойств

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

-Translate

Translate используется в основном для перемещения элементов по осям x и y. У него есть такие атрибуты:

FromXDelta и fromYDelta показывают, с какого направления будет появляться элемент. Если вы установите положительное значение для «fromXDelta», оно будет появляться с правой стороны экрана. Атрибуты ToDelta представляют, где элемент будет останавливаться. Обычно я использую атрибут toDelta в 0%. Потому что даже если вы установите «-100%», когда анимация закончится, элемент вернется на экран, и это будет выглядеть не очень красиво. И, наконец, «продолжительность» — это время анимации. Давайте посмотрим на анимацию со свойством только translate.

-Alpha

Alpha используется для определения непрозрачности. Это свойство в основном используется для анимации постепенного появления/исчезновения. Атрибуты указаны ниже:

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

-Rotate

Свойство Rotate, как можно понять из названия, используется для анимации вращения для элементов представления.

Эти атрибуты вначале сбивали меня с толку, поэтому я постараюсь объяснить их как можно яснее. Атрибут FromDegrees представляет, с какого угла элемент будет разворачиваться. Представьте себе градусы и посмотрите на изображение сейчас. Элементы начинаются с угла 270 ° и вращаются по часовой стрелке. Атрибуты Pivot похожи на закрепление элемента в соответствии с их значением. Например, если вы установите pivotX: 100%, pivotY: 0% и fromDegrees: 90 °, приложение закрепит элемент в правом верхнем углу и соответственно повернет его. Анимацию можно увидеть на гифке ниже.

-Scale

Свойство Scale используется для масштабирования элементов. Этих атрибутов больше, чем других, поэтому давайте углубимся в них.

Атрибуты Pivot здесь выполняют немного другую функцию. Значение 50% для обоих атрибутов представляет центр элемента. Я установил это так, потому что хочу масштабировать их от центра. Атрибуты FromScale и ToScale используются для масштабирования элемента. 1 для исходного размера и 0 для начального размера. Эти атрибуты делаю то, что вы видите ниже.

-Setting up

Прежде всего, вам нужно определить View, который вы хотите анимировать, для элемента RecyclerView в адаптере. После этого вы можете использовать приведенный выше фрагмент кода в OnBindViewHolder, чтобы добавить свои анимации. Я хочу анимировать весь элемент, поэтому я определил представление карточки shopDetailParent в адаптере. Example_anims — это мой файл анимаций, поэтому вам нужно использовать в коде собственное имя файла.

Читайте также:  Usb файловый менеджер для андроид

Некоторые красивые примеры анимации

Интерполяторы

У нас есть последний атрибут — интерполяторы. Интерполяторы — это в основном поведение анимаций. Обычно анимация работает с линейным интерполятором. Этот интерполятор равномерно перемещает представление по каждому кадру анимации. (Все графики с этого момента взяты с jebware.com, вы можете зайти на сайт и попробовать интерполяторы с разными коэффициентами) И его график такой:

Но у других интерполяторов другие графики. Я покажу вам, как добавлять интерполяторы, и покажу пару примеров, после чего вы можете попробовать поработать с ними самостоятельно. Все, что вам нужно сделать, это добавить эту строку в свой set.

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

Список интерполяторов от developer.android. Но также вы можете писать собственные интерполяторы.

Спасибо, что прочитали мою статью. Я пытался объяснить то, что знаю. Надеюсь, это поможет вам понять и сделать красивую анимацию для RecyclerView 🙂

Источник

Анимируем RecyclerView легко без перехода на ViewPager2

Когда мы работаем с коллекциями и их отображением, перед многими из нас часто
встает выбор между ViewPager (теперь ещё и ViewPager2 ) и RecyclerView . Эти
компоненты похожи друг на друга по области применения, но серьезно отличаются
интерфейсом и реализацией. Начиная с support library 24.2.0 границы между
данными компонентами стали ещё более размытыми, т.к. появился вспомогательный
класс SnapHelper для автоматического доведения сhildView до
определенного положения на экране, и без устаревшего ViewPager стало проще
обходиться. С недавним релизом ViewPager2 , казалось бы, о старом ViewPager и о
практиках его имитации вообще можно забыть ( ViewPager2 — это по сути
RecyclerView с дополнительными вспомогательными классами, он позволяет
практически идентично повторить поведение ViewPager и сохраняет совместимость со
старым api).

Так ли это на самом деле? Лично для меня всё оказалось не так просто. Во-первых,
в классическом RecyclerView отсутствует интерфейс PageTransformer для
анимирования сhildView в зависимости от позиции (далее по тексту используется
понятие «позиционная анимация»). Во-вторых, неприятными сюрпризами долгожданного
ViewPager2 оказались модификатор класса final , который ставит крест на
переопределении метода onInterceptTouchEvent (компонент мало пригоден для
вложения горизонтальных списков в вертикальные), и приватность поля
recyclerView .

Итак, столкнувшись в очередной раз с трудностями позиционной анимации при
отображении коллекций с помощью RecyclerView и поковырявшись в ViewPager2 и
MotionLayout , я подумал, что позаимствовать принцип работы
ViewPager.PageTransformer для классической реализации RecyclerView а-ля
ViewPager2 не самая плохая идея.

Задача, в контексте которой это затевалось, была достаточно необычной:

  • сделать компонент для отображения коллекции в горизонтальном и вертикальном
    представлении
  • горизонтальный список должен повторять поведение ViewPager и пролистываться
    со sticky-эффектом
  • при движении нижней “шторки” ( BottomSheetBehavior ) должна происходить
    анимированная трансформация ориентации списка — выпадение элементов лесенкой
  • должна быть возможность выбора элемента из вертикального списка с
    анимированным сдвигом остальных элементов влево и последующим превращением
    вертикального списка в горизонтальный.
    Запутались? Вот вам пример такого горизонтально-вертикального списка в
    интернет-банкинг приложении «Мой кредит» Банка Хоум Кредит:
Читайте также:  Андроид авто пежо 3008 как включить

1. Делаем компонент для анимированного списка

Сам компонент было решено спроектировать как наследника ConstraintLayout с двумя
recyclerView внутри. Прогресс анимации берется из BottomSheetCallback нашего
BottomSheetBehavior :

У компонента есть метод transformation , принимающий прогресс “превращения” как
аргумент.

2. Решаем проблему позиционного анимирования

Реализацию анимации я начал с интерфейса для позиционной анимации — аналога
ViewPager.PageTransformer.

Идея была такой — есть абстрактный класс ItemViewTransformer с абстрактным
методом transformItemView , повторяющим сигнатуру метода transformPage интерфейса
ViewPager.PageTransformer :

В attachToRecycler происходит инициализация свойства recyclerView и слушателей
RecyclerView.AdapterDataObserver и RecyclerView.OnScrollListener :

После вызова updatePosition происходят вызовы метода transformItemView для
каждого видимого childView с передачей в аргументы текущей позиции относительно
левого края (такой расчет позиции справедлив только для childViews одинаковой
ширины/высоты с учетом отступов):

Начиная с этого момента, вы можете взять, например, свой старый добрый
pageTransformer , на который вы когда-то потратили так много времени, и
переиспользовать его код для recyclerView .

3. Sticky-эффект горизонтального списка

В примере выше sticky-эффект реализован как раз с помощью этого абстрактного
класса. В имплементации метода размер и положение описываем простейшими
кусочными функциями:

Аттачим наш BouncingTransformer сразу после инициализации адаптера и
recyclerView:

После компиляции мы получим пролистывание списка со sticky-эффектом:

В общем-то, ничто не мешает анимировать список, например, как колоду карт, и не
придется прибегать даже к помощи ItemDecoration .

4. Делаем универсальный прогресс-аниматор

Следующим этапом был реализован аналогичный интерфейс для выполнения
value-анимации с абстрактным методом onUpdate :

Здесь attachToRecycler инициализирует лишь свойство recyclerView :

Методом update задается прогресс анимации для видимой позиции или позиции
адаптера:

5. Трансформация списка

Теперь мы можем описать трансформацию “лесенкой” вертикального recyclerView в
имплементации метода onUpdate :

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

6. Эффект разбегания для горизонтального списка

Этой трансформации должен предшествовать эффект “разбегания” вьюшек в
горизонтальном списке:

Получаем желаемое поведение:

7. Анимация выбора элемента в вертикальном списке

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

Либо классически с помощью ItemAnimator :

Получаем похожее поведение:

Завершаем трансформацию списка выездом правого видимого элемента горизонтального
списка:

После компиляции видим:

8. Результаты

По большому счету на этом реализация анимации завершена. Что в итоге мы
получили:

  • отказались от использования ViewPager, что, как минимум, обещает лучшую
    консистентность адаптеров, а значит и более удобный data building
  • получили преимущества ViewPager.PageTransformer — удобное позиционное
    анимирование
  • сохранили преимущества RecyclerView — более экономное потребление ресурсов,
    гибкую систему нотификации изменений адаптера, ItemAtimator, ItemDecoration
  • не добавляли новые зависимости в проект
  • реализовали достаточно сложную анимационную последовательность на основе
    всего двух новых абстрактных классов.

Надеюсь, эта статья окажется для вас полезной. Удачи!

Источник

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