Векторная анимация в 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, Файлы замка.