Path data android studio

Класс Path

Класс android.graphics.Path (контур) позволяет создавать прямые, кривые, узоры и прочие линии. Готовый путь затем можно вывести на экран при помощи метода canvas.drawPath(path, paint).

Рассмотрим базовый пример с применением некоторых методов класса.

Создадим новый класс, наследующий от View:

Подключим его к главной активности, чтобы вывести на экран:

Методы

Метод reset() очищает объект Path.

Метод moveTo() ставит кисть в указанную точку, с которой пойдёт новая линия.

Метод lineTo() рисует линию от текущей точки до указанной, следующее рисование пойдёт уже от указанной точки.

Метод close() закрывает контур.

Методы addRect(), addCircle() добавляю к контуру прямоугольник и окружность. В методах используется параметр, отвечающий за направление. Есть два варианта: Path.Direction.CW (по часовой) и Path.Direction.CCW (против часовой).

Метод cubicTo() рисует кубическую кривую Безье. По аналогии можете изучить другие методы.

Методы moveTo(), lineTo(), quadTo(), cubicTo() имеют методы-двойники, начинающиеся с буквы r (relative): rMoveTo(), rLineTo(), rQuadTo(), rCubicTo(). Данные методы используют не абсолютные, а относительные координаты.

Спроектируем лестницу при помощи метода lineTo().

Проверяем, удобно ли спускаться. Теория — это одно, а практика — это совсем другое.

Эффекты

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

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

  • CornerPathEffect. Позволяет сглаживать острые углы в форме графического примитива, заменяя их на закругленные.
  • DashPathEffect. Вместо рисования сплошного контура можете использовать DashPathEffect для создания очертания, состоящего из ломаных линий (тире/точек). Есть возможность указать любой шаблон повторения сплошных/пустых отрезков.
  • DiscretePathEffect. Делает то же самое, что и DashPathEffect, но добавляет элемент случайности. Указываются длина каждого отрезка и степень отклонения от оригинального контура.
  • PathDashPathEffect. Позволяет определить новую фигуру (контур), чтобы использовать ее в виде отпечатка оригинального контура.
  • SumPathEffect. Добавляет последовательность из двух эффектов, каждый из которых применяется к оригинальному контуру, после чего результаты смешиваются;
  • ComposePathEffect. Использует первый эффект, затем к полученному результату добавляет второй.

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

Контурные эффекты применяются к объекту Paint с помощью метода setPathEffect()

DashPathEffect

Сплошную линию можно сделать пунктирной с помощью класса DashPathEffect. Перепишем немного код.

Вам нужно указать длину отрезка для пунктира и длину отрезка для разрыва между двумя отрезками пунктира. Эта комбинация будет циклично использована для прорисовки всей линии. Пунктирная линия может быть сложной. Задайте массив для переменной intervals, чтобы увидеть разницу.

Упрощённый вариант для Kotlin с применением Bitmap в ImageView.

Вместо точек можно вывести пунктирную линию, исправив одну строчку кода.

CornerPathEffect

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

PathDashPathEffect

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

Бегущие муравьи

Вы все встречали эффект «бегущие муравьи» в графических редакторах. Применим его к объекту класса PathDashPathEffect, увеличивая смещение.

На странице Effect of advance, phase, style in PathDashPathEffect автор примера поиграл с параметрами.

DiscretePathEffect

DiscretePathEffect позволяет «сломать» прямую линию, чтобы получить ломаную с элементом случайности. Полученная ломанная линия будет состоять из отдельных отрезков. Мы можем воздействовать на длину и степень излома.

Показать код (ткните лапой)

SumPathEffect

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

Суммируем эффекты CornerPathEffect и DashPathEffect. Для наглядности я чуть изменил параметры у эффектов, чтобы было виден результат наложения двух эффектов на лестницу — вы должны увидеть две линии — прерывистую и скруглённую.

Показать код (щелкните мышкой)

ComposePathEffect

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

Заменим класс SumPathEffect на ComposePathEffect из предыдущего примера и посмотрим на результат.

Пример

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

Примеры с контурами

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

В класс PathView внесём изменения.

Добавим в разметку компонент SeekBar, чтобы динамически менять размер контура.

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

Усложним пример. Будем использовать не только окружность, но и другие фигуры. Добавим в класс Shape метод setPolygon():

Класс PathView потребует небольшой переделки.

В разметке до компонента PathView добавьте пару новых компонентов.

Код для активности.

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

Следующий этап — создание звёзд, пятиконечной, шестиконечной и т.д.

Опять добавим код в класс Shape.

Внесём изменения в класс PathView.

Чтобы закруглить углы у звёзд, применим эффект CornerPathEffect. Добавим код в конструктор класса Shape.

Чтобы залить фигуру цветом, нужно использовать вместо стиля Paint.Style.STROKE стиль Paint.Style.FILL или Paint.Style.FILL_AND_STROKE.

Вращение

Чтобы вращать контур, нужно создать объект класса Matrix и вызвать метод postRotate().

Добавим в класс PathView две новых переменных.

Добавим строчку кода в метод init():

Добавим код в onDraw():

Добавим новый метод.

Добавим в разметку активности ещё один SeekBar

И добавляем код в класс активности:

Вращать можно не только сам контур, но и холст вместо него. Эффект будет такой же, а по потреблению ресурсов даже может оказаться эффективнее. Закоментируем использование класса Matrix и добавим вызов метода Canvas.rotate() в методе onDraw() класса PathView.

Читайте также:  Нет мелодии входящего звонка андроид

Теперь создадим эффект «бегущих муравьёв» при помощи PathDashPathEffect:

Источник

Understanding VectorDrawable pathData commands in Android

If you want to animate Vectors, you need to understand what these commands mean.

Aug 26, 2016 · 6 min read

Open any VectorDrawable XML file and you are greeted with some cryptic commands in the pathData attribute.

Those who works with Paths on a regular basis may be able to interpret this command and tell you what shape it makes. For the rest of us, it can be a bit of a mystery.

What is a VectorDrawable

A VectorDrawable is an XML representation of a V ector. Unlike popular image formats like Bitmap, JPEG, GIF and PNG, Vectors do not lose quality as they are scaled up or down. This makes bundling of images with different densities unnecessary, hence saving you a lot of APK bloat. In effect, VectorDrawables contains path commands on (how to draw lines and arcs) and just like Path commands when working with Canvas, drawing and rendering VectorDrawables is time and memory consuming process which is why VectorDrawable’s are best used for simple flat graphics.

Why bother to understand these commands? I just get them as an SVG!

If you wish to animate a VectorDrawable, as is all the rage these days, one of the requirements is that the VectorDrawable you are animating from and to should share the same number of commands. Also, it helps to know how each of these commands will cause the graphic to move/change in order to animate the image. To this end, having an understanding of what these path commands mean can help greatly.

Understanding pathData commands

Let me just start by saying that no matter how much you study path commands, unless you’re a genius, there will be a limit to what you can understand. Vector graphic programs don’t exactly have clean and human readable code as a high priority. After vector graphics files like SVGs are piped through Android Studios VectorDrawable generator, they become a lot cleaner and easier to read, however, I’ve found that a lot of the commands can still be a lot more complex that what you may need. Then to understand circles and arcs just requires you to have a lot of imagination or some serious mathematics prowess.

The basics

Basic path commands are comprised of alphabet followed by one or more numbers. The numbers are often comma separated but don’t have to be. E.g.

The alphabet can be upper or lowercase. Uppercase means absolute position, lowercase means relative position.

Commands

M or m (X,Y)+
moveto: Move cursor to position, uppercase is absolute, lowercase is relative
moveto commands are followed by X,Y coordinates. There can be more than one set of coordinates following an M command, these are treated as implicit lineto commands.

Z or z
closepath: Draws a line from the current position of the cursor to the start position of the path. Does not have any parameters.

L or l (X,Y)+
lineto: Draws a line from the current position to the position specified by X,Y. Uppercase means absolute coordinates, lowercase means relative coordinates. You can have more than one set of coordinates following a lineto command. If you want specify more than one set of coordinates, it means that you’re creating a polyline (shape consisting of multiple string lines).

H or h (X)+
Horizontal lineto draws a horizontal line from the current cursor position to the position specified by X. If there are multiple X coordinates following the command, this is treated as a polyline. The Y coordinate remains unchanged. Uppercase H is absolute coordinates, lowercase h is relative coordinates.

V or v (Y)+
Vertical lineto draws a vertical line from the current cursor position to the position specified by Y. If there are multiple Y coordinates following the command, this is treated as a polyline. The X coordinate remains unchanged. Uppercase V is absolute coordinates, lowercase v is relative coordinates.

Example

With this much in mind, lets interpret the command we had above:

M100,100: Move cursor to absolute coordinates X=100 Y=100px.
L300,100: Draw a line to X=300 Y=100 (starting position was 100,100).
L200,300: Draw a line to X=200 Y=300 (starting position was 300,100).
z: Close path, straight line from current position to 100,100. When you close the path is when the shape is filled with the fill colour specified. You can leave this out if you shape doesn’t need to close, like in a check mark or a cross.

If we sketch it out, you’ll notice that the shape is an upside down triangle!

If we put this inside a simple VectorDrawable XML we can see the result:

Источник

Vector Drawable API. Возможности применения

2014 год был особенным для всех, кто занимается разработкой под Android — он принес одно из самых значимых обновлений Android за всю его историю, версию Android 5.0. С этим обновлением мы получили новый визуальный язык, детальные гайдлайны, множество новых API и инструментов. И, как всегда в случае таких массивных обновлений, не все новшества сразу пробивают себе дорогу в реальные проекты. Где-то мешает инерция мышления разработчиков, привыкших решать определенные задачи определенным образом, где-то — отсутствие документации по новым API, где-то — отсутствие поддержки новых возможностей на старых версиях платформы. Но время не стоит на месте и благодаря труду команды Android, а также независимых разработчиков, такие API постепенно обретают обратную поддержку. И сегодня я хочу рассказать об API векторной графики Android, который способен серьезно облегчить жизнь разработчика, но при этом до сих пор не пользуется популярностью.

Material Design и векторная графика

Как же мы можем использовать поддержку векторной графики, появившуюся с выходом Android 5.0? Для ответа на этот вопрос необходимо рассмотреть Material Design не просто как новый стиль оформления Android, а как часть более общего тренда в дизайне интерфейсов, начало которому было положено с выходом интерфейса Metro в Windows 8. Затем был Flat Design в iOS 7 и Material Design в Android. Ключевыми характеристиками этого стиля, истоки которого можно искать в работах представителей школы Баухаус, а также в направлении т.н. швейцарской школы типографики, являются отказ от скефоморфизма, использование простых и выразительных цветов, четкая структура верстки.

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

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

Переход на векторный формат изображений дает нам ряд преимуществ: нам не нужно нарезать набор иконок под все разрешения экрана, не нужно перерезать его заново в случае каких-то изменений, дополнительно необходимо отметить снижение размера установочного пакета с приложением, а также снижение нагрузки на оперативную память, требуемую для загрузки текстур и иконок в png. Некоторое время назад в техническом блоге Instagram появилась статья, где инженеры сервиса описывали процесс редизайна приложения по гайдам Material Design. По их данным переход на Material Design и, сопутствующее ему, «уплощение интерфейса» позволили сократить время запуска приложения на 120 мс.
Надеюсь, после таких аргументов вы захотели использовать векторную графику и сейчас я перейду к детальному разбору структуры API и методов работы с ним.

Класс VectorDrawable

Тэг Vector

Основой API векторной графики в Android является класс VectorDrawable . Объекты этого класса являются ресурсами и описываются при помощи языка XML, размещаются они в директории res/drawable нашего проекта. Корневым элементом класса является тэг vector . У тэга vector есть несколько атрибутов, обязательными являются две группы атрибутов, которые определяют размер изображения нашего drawable . Я говорю об атрибутах width и height — они указываются с использованием неких единиц измерения (набор их стандартен для Android — dp , sp и px ), а также viewportWidth и viewportHeight — они указываются без единиц измерения. При помощи width и height мы можем указать физический размер, который займет наш drawable на экране, а viewport можно сравнить с окошком, через которое мы смотрим на наше изображение. Размеры viewport могут как совпадать, так и отличаться от размеров изображения. При этом, изменяя размер viewport , мы можем изменять площадь занимаемую фигурой внутри drawable .

Стоит отметить, что у viewport отсутствует возможность задать координат pivotPoint и изменения размеров viewport будут отсчитываться от левого верхнего угла. Также у элемента vector есть ряд других атрибутов, смысл которых ясен из названия.

Элемент Path

Главное, без чего не может обойтись ни один файл VectorDrawable — это тэг Path . У элемента Path самый главный атрибут — это атрибут pathData . Его значением является строка символов, разделенных запятыми. Эти символы не что иное, как команды формата SVG.

SVG — это формат векторной графики, разработаннный специально для интернета, и он поддерживается всеми современными браузерами, а также экспорт в SVG доступен из большинства графических редакторов. SVG поддерживает набор примитивных фигур, таких как овал, прямоугольник, спираль и пр., а также фигуры произвольной формы. Фигуры произвольной формы описываются при помощи набора команд, которые представляют из себя координаты точек и отрезков прямых, кривых Безье и дуг, их соединяющих. Выполнив последовательно эти команды возможно построить требуемую нам фигуру.
Поскольку для описания файлов SVG также используется язык XML, мы можем открыть его в текстовом редакторе и найти объект Path . У этого объекта будет присутствовать атрибут d , значением которого будет строка с командами, идентичными тем, что мы можем найти в качестве значения атрибута pathData объекта Path в ресурсе VectorDrawable. Это обстоятельство позволяет нам легко создавать ресурсы VectorDrawable — для этого достаточно скопировать набор команд из файла в формате SVG в наш ресурс VectorDrawable.

Для того, чтобы мы могли увидеть нашу фигуру мы должны ей назначить заливку и, опционально, обводку. Делается это при помощи атрибутов fillColor, strokeColor, strokeWidth. Стоит отметить, что, в отличие от SVG, фигура в VectorDrawable не может иметь градиентную заливку — только определенный цвет.

Элемент Group

Самый простой векторный файл содержит только одну фигуру, однако в сложных изображениях количество таких фигур может исчисляться десятками. Для удобства работы с ними отдельные фигуры можно объединять в группы, используя элемент Group . Возможность объединять несколько объектов Path в группу позволяет не только упорядочить структуру нашего drawable-ресурса, но и дает возможность применить групповые настройки к набору объектов, но самое главное, что группа может использоваться для анимации, о чем мы поговорим далее.
Таким образом, в одном ресурсе VectorDrawable мы можем создавать сложную графику, используя различные объекты Path , которым можно задавать свой собственный цвет, прозрачность, обводку, указывать положение на экране. Объекты Path можно объединять в группы, для которых опять же можно указывать ряд групповых атрибутов. Самое интересное, что все атрибуты можно заанимировать, при этом для применения одной анимации к набору объектов Path , удобно эти объекты объединить в группу.

Класс AnimatedVectorDrawable

Второй частью API векторной графики, появившегося в Android Lollipop, является класс AnimatedVectorDrawable , который позволяет создавать анимации для классов VectorDrawable. AnimatedVectorDrawable представляет собой расширение PropertyAnimation, которая дает нам возможность создания анимаций, основанных на изменении значений любых атрибутов объекта. Файлы AnimatedVectorDrawable тоже относятся к ресурсам приложения и создаются с использованием XML. Корневым элементом ресурса векторной анимации является тэг animated — vector. У этого тэга только один атрибут drawable , в котором мы указываем имя ресурса VectorDrawable, для которого мы хотим создать анимацию. Внутри элемента animated-vector располагаются объекты target , которые представляют собой цели для анимаций. Наиболее замечательным является то, что animated-vector может содержать более одного target . Этот факт дает возможность создавать сложные анимации, позволяя анимировать различные части изображения при помощи различных анимаций, создавая комплексные анимации.

В частности знаменитая анимация hamburger-to-arrow, так очаровавшая всех в момент анонса Android 5.0, легко создается с использованием векторной анимации: верхняя и нижняя полосочки гамбургера движутся навстречу средней, одновременно с этим вся группа вращается на 180° — здесь мы указываем три target и создаем для них три анимации.

Читайте также:  Viva cut pro андроид

У элемента target есть два главных атрибута — name , в котором мы указываем имя объекта Path или объекта Group , который будет анимироваться, и animation , куда мы передаем ссылку на ресурс анимации, размещаемый в папке res/anim .

Ресурс анимации это стандартный animator-set , c объектом objectAnimator внутри. В качестве значения атрибута propertyName мы можем указать любой атрибут объекта Path или Group из VectorDrawable. В зависимости от типа атрибута мы должны указать соответствующий тип значений в атрибуте valueType .
Android Lollipop с появлением нового типа графики принес и новый тип property , для которого можно создать анимацию — это анимация значения атрибута pathData у объекта Path . Для этого в поле propertyName появилось новое значение pathData и соответствующее ему значение valueType — pathType . При этом старые поля valueFrom и valueTo принимают в качестве аргументов две строки с наборами команд, описывающие соответственно начальную и конечную форму фигуры. Благодаря этому новому типу анимаций можно создавать сложные анимации, преобразующие форму фигуры, ранее недоступные в Android — например анимации морфинга, преобразующие кнопку Play в кнопку Pause. Сам Google рекомендует сохранять данные с командами path в строковых ресурсах.
Стоит заметить, что для успешной работы анимации количество команд и тип команд в исходном и конечном пути должно быть одинаковым. В противном случае вы получите исключение времени выполнения. Данное суровое условие в свое время отняло у меня много времени, но недавно появился инструмент VectAlign, позволяющий автоматически выровнять две строки с путями по числу и типу команд.

Запуск анимации

Файлы с векторной анимацией реализуют интерфейс Animatable и для запуска анимации, мы запрашиваем Drawable , приводим его к Animatable и вызываем метод start() .

Интерфейс Animatable крайне прост — в нем только три метода: isRunning() , start() , stop() . Таким образом отсутствует возможность задания AnimationListener . Также отсутствует возможность передать нашу векторную анимацию в AnimatorSet . Поэтому прямая возможность создавать хореографию анимаций, или запускать какие-то действия по завершению анимации отсутствует. Точнее, отсутствовала — в 23 версии Android SDK интерфейс Animatable был расширен новым интерфейсом Animatable2 , который позволяет для нашей векторной анимации регистрировать AnimationCallback .
Для версий до 23 для хореографии можно использовать возможности отложенного запуска, например при помощи метода Handler.postDelayed() .

Обратная поддержка

Возвращаясь к тому, с чего я начал, хочу напомнить, что внедрению векторной графики в проектах до сих пор мешало отсутствие обратной поддержки этого функционала на версиях Android = 14. И я говорю о библиотеках VectorCompat и BetterVectorDrawable. Сам я имею опыт работы только с библиотекой VectorCompat, поэтому буду говорить только о ней. Интересующихся тонкостями работы с BetterVectorDrawable отсылаю к циклу статей astudent: часть 1, часть 2;
Для того, чтобы ресурсы с векторной графикой работали через библиотеку обратной совмести, нам необходимо выполнить ряд условий. Во-первых, в ресурсах XML, которые описывают наши VectorDrawable и анимации для них, необходимо продублировать ряд атрибутов, таких как, viewportHeight, viewportWidth, fillColor, pathData, valueType с нэймспэйсом библиотеки VectorCompat.
Другое ограничение выражается в том, что мы не можем VectorDrawable напрямую указать, как background для view в XML-ресурсе макета. Для использования VectorDrawable мы должны загрузить его из XML-ресурса в java-коде и уже там указать его как фон для ImageView.
Библиотека предлагает три метода для загрузки VectorDrawable из XML: VectorDrawable.getDrawable(), AnimatedVectorDrawable.getDrawable() и ResourcesCompat.getDrawable() . Третий метод предпочтительнее по двум причинам: во-первых при его использовании нет разницы, объект какого класса мы пытаемся загрузить — VectorDrawable или AnimatedVectorDrawable, а во-вторых, на устройствах с Lollipop и выше, автоматически будет использовать нативный метод из Android SDK.
В остальном, никаких других особенностей использования векторной анимации с использованием библиотеки VectorCompat нет.

Подготовка векторных файлов

В заключение необходимо обсудить тему подготовки файлов векторной графики для Android. Экспорт в формат SVG поддерживается большинством векторных редакторов, в том числе Corel Draw, Adobe Illustrator и Sketch. Однако, при использовании Adobe Illustrator возникает проблема с позиционированием изображения относительно viewPort — несмотря на то, что при просмотре в Illustrator изображение отцентрировано относительно viewPort , при открытии экспортированного SVG файла, к примеру, в браузере, оказывается смещен в сторону. Поэтому для использования SVG файлов из Illustrator предварительно их нужно пересохранить в другой программе, например бесплатной Inkscape.
При этом не стоит забывать о том, что из всего множества SVG Android поддерживает только объекты Path . Поэтому примитивные фигуры, необходимо трансформировать в пути. В Sketch это делается командой Layer > Paths > Vectorize stroke, а в Illustrator > Object > Expand.
Имея в наличии файл SVG мы можем открыть его в текстовом редакторе и найти тэг . В нем нас интересует атрибут, озаглавленный d — его значением является строка с командами. Скопировав эту строку, мы можем сохранить ее в нашем проекте и использовать в качестве значения атрибута pathData в файле VectorDrawable.
К сожалению, в Android Studio на данный момент отсутствует возможность редактирования векторных файлов, однако эта возможность должна появиться в будущих версиях. Также в версии 1.4 появился новый инструмент Vector Asset Studio — мы можем указать SVG файл и Vector Drawable из этого SVG будет создан автоматически. Для этого мы должны перейти в папку res/drawable и вызвать его через меню File > New > Vector Asset.

Пока что версия 1.4 находится в стадии Preview и мне удалось заставить ее работать только с SVG файлами из Illustrator. Также минимальная версия вашего проекта должна быть установлена (хотя бы на время импорта) на значение 21. Помимо этого поддерживается выбор из набора иконок Material Design. Использование данного инструмента избавляет от необходимости вручную копировать данные пути из SVG файлов, что может быть особенно востребованным, когда наше изображение состоит из множества фигур. Также в версии 1,4 Android плагина для Gradle должна появиться функция генерации набора png-файлов из векторных ресурсов при сборке проекта.
Широкое распространение SVG формата, а также наличие поддержки векторной графики на старых версиях Android снимают последние возражения относительно ее использования в реальных проектах. Требуйте от дизайнеров иконки в векторе и это избавит от необходимости готовить набор png файлов под все разрешения в случае изменения дизайна, также это позволяет уменьшить вес готового apk-файла. Всем vector!

Источник

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