April 12, 2020

Векторная анимация в Android (часть 1)

Уже довольно давно в Android существует возможность использовать векторные ресурсы вместо png нарезки. Такая возможность появилась с релизом Android 5.0 Lollipop и API 21. Для более ранних версий системы мы можем использовать AppCompat (библиотека совместимости), благодаря которой статичный вектор будет работать с API 7 (Android 2.1), а анимированный – с API 11 (Android 3.0 Honeycomb).

Векторные ресурсы, в отличие от обычной нарезки, занимают примерно в 10 раз меньше места. Нет необходимости адаптировать графику под разные плотности экранов. Кроме того, можно переиспользовать ресурс в разном контексте, размере и цвете.

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

Вектор в Android?

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

К сожалению (или к счастью), в Android нельзя использовать svg файлы напрямую, по крайней мере, без использования сторонних библиотек. Причина очень проста и состоит в том, что SVG формат очень комплексный и богатый на возможности и поддержка столь богатого функционала сложна и не целесообразна для таких простых вещей как иконки, ну и не стоит забывать о проблеме производительности и совместимости. Именно поэтому в Android используют более простой формат, который, тем не менее, во многом похож на svg.

Векторная графика представлена в виде двух классов VectorDrawable и AnimatedVectorDrawable. Из названия классов понятно, что первый отвечает за статичный вектор, а второй – за его анимацию. Классы описываются обычным XML ресурсом.

Для начала рассмотрим VectorDrawable, который имеет следующую структуру:

В элементе <vector> содержатся параметры высоты и ширины объекта. Внутри есть элемент <group>, который может содержать в себе элементы <path> и <clip-path>, а также другие группы. В параметрах элемента <group> указывается информация о трансформации (смещении, масштабе и угле) и имени, которое мы будем использовать для применения анимации. Элементы <path> и <clip-path> описывают геометрию и цвет объекта.

Для того чтобы добавить анимацию, мы используем класс ObjectAnimator, который просто применяем на объекты VectorDrawable. Мы можем применять анимацию как к общей группе, так и к конкретному <path>. Анимация может представлять собой как простую манипуляцию параметрами объекта, так и сложный морфинг.

Раньше для реализации анимации в приложении необходимо было использовать как минимум 3 xml файла: 1 файл для VectorDrawable, который необходимо анимировать, другой для аниматора, описывающего анимацию, и последний файл — объединяющий непосредственно аниматор и VectorDrawable. Чем сложнее анимация, тем больше файлов необходимо создавать, что часто приводило к путанице.

На Google I/O 2016 был представлен новый формат — XML bundle. Он позволяет описывать векторную анимацию одним файлом.

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

Готовим вектор под Android

Для начала нам нужен любой графический редактор, который умеет на выходе выдавать svg файл. К счастью, их великое множество: Photoshop, Illustrator, Sketch, Inkscape, Affinity Designer и т.д.

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

Для примера я сделал простую иконку замка и разделил её на два шейпа (группы) для последующей анимации. Сохраняем в svg и обязательно проверяем корректность экспорта. Очень часто проблемы возникают со stroke и от избыточной вложенности объектов. Как правило, старайтесь по максимуму объединять всё в один объект, а stroke переводить в shape (outline).

Конвертация SVG в XML

Есть несколько способов сделать конвертацию svg файла в xml.

Первый способ — это сделать всё руками. Это конечно, не очень удобно, но ничего сложного тут нет. Просто переносим куски из svg в xml используя правильные имена параметров. Ниже я выделил куски, которые практически полностью совпадают.

Второй способ — в Android Studio есть инструмент Vector Asset Studio, который позволяет автоматически выполнить перевод SVG файла в XML. Ресурсы можно выбирать из библиотеки иконок или указать свой SVG файл. Благодаря превью можно сразу оценить корректность экспорта. Есть полезные настройки.

Третий способ — это использовать онлайн инструменты, например http://inloop.github.io/svg2android/. Лично я предпочитаю именно его, так как в нем есть полезные настройки по оптимизации файла и самое главное — возможность выгрузить и забрать все пакетом. К сожалению, нет превью результата.

Еще один онлайн конвертер — https://svg2vector.com/

В первой части мы подробно рассмотрели структуру векторных ресурсов в Android и способы конвертации ресурсов из svg в xml. В следующей части мы рассмотрим несколько способов работы с анимацией.

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

Все используемые материалы можно найти на GitHub: XML Bundle, Файлы замка.

Источник: Векторная анимация в Андроид (Часть первая)