Using path in android

Класс 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:

Источник

Полный список

— работаем с Path

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

Читайте также:  Хороший аудио плеер для андроида

Project name: P1431_DrawingPath
Build Target: Android 2.3.3
Application name: DrawingPath
Package name: ru.startandroid.develop.p1431drawingpath
Create Activity: MainActivity

Простые фигуры

Кодим в MainActivity.java:

Метод reset очищает path.

Метод moveTo – ставит «курсор» в указанную точку. Далее рисование пойдет от нее.

lineTo – рисует линию от текущей точки до указанной, следующее рисование пойдет уже от указанной точки

Таким образом мы нарисовали две прямые, получился угол.

Далее перемещаем точку и снова рисуем две линии, и закрываем подфигуру методом close. Методом moveTo мы сообщили, что начали рисовать новую подфигуру и эта точка является начальной, а когда вызываем close – рисуется линия от последней точки до начальной. Т.е. фигура закрывается. Таким образом, нарисовав две линии и вызвав метод close, мы получили треугольник.

Далее методами addRect и addCircle к объекту path добавляем квадрат и круг. Параметры тут стандартные, рассмотрены нами на прошлых уроках, кроме последнего: направления. Здесь есть два варианта: Path.Direction.CW (по часовой) и Path.Direction.CCW (против часовой). Т.е. вы задаете направление рисования линий квадрата или фигуры. Как это можно использовать, рассмотрим чуть позже.

Выводим получившийся path на экран ченым цветом.

Далее работаем с другим Path-объектом: path1. Добавляем в него две пересекающиеся линии. Выводим path1 зеленым цветом. Он у нас получился нарисован поверх path.

Теперь методом addPath добавляем path1 к path. Т.е. к Path можно добавлять не только фигуры и линии, но и Path-объекты. Смещаем итоговый path на 500 вправо и 100 вниз методом offset, меняем цвет на синий и выводим результат.

В хелпе есть еще несколько методов add* для добавления фигур, которые мы прошли в прошлом уроке. С ними все аналогично.

Кривые

Path дает нам возможность рисовать не только прямые, но и кривые линии, а именно квадратичные и кубические кривые Безье. Википедия дает очень хорошие GIF-ки на эту тему.

Перепишем класс DrawView:

Рассмотрим сначала зеленую кривую.

Сначала рисуем черную линию (100,100) – (600,100). Делаем это только для наглядности, чтобы видеть, какой была бы линия, если бы мы из нее кривую не сделали.

Далее нарисуем небольшой круг в точке, которая будет использована для искривления линии. Делаем это тоже только для наглядности, чтобы видеть в каком направлении будет искривлена прямая. Координаты точки заданы в объекте point1.

Теперь рисуем кривую, используя Path. Становимся в точку (100,100) методом moveTo. Метод quadTo рисует кривую из текущей точки (100,100) в точку (600,100) (т.е. те же координаты, что и черной линии). А точка (point1.x, point1.y) позволяет задать изгиб кривой. Проще говоря, кривая будет отклонена в сторону этой точки.

Аналогично рисуем синюю кривую. Сначала черным цветом прямой оригинал. Затем точки отклонения. Затем искривляем. Метод cubicTo рисует кривую из текущей точки (400,400) в точку (1100,400). А точки (point21.x, point21.y) и (point22.x, point22.y) позволяют задать изгиб кривой. Проще говоря, кривая будет отклонена в сторону этих точек.

Читайте также:  Блок оригинал для андроид

На получившемся результате видно, что кривые тянутся к точкам, которые показаны кружками. Для зеленой кривой, нарисованной методом quadTo – это одна точка. А метод cubicTo позволил нам задать две такие точки для синей линии.

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

В качестве задания предлагаю вам вспомнить Урок 102 про касания и сделать приложение, в котором будет нарисована прямая, а касаясь экрана пальцем ее можно будет искривлять в сторону точки касания.

Относительные методы

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

Например, если метод lineTo(100,200) рисовал нам линию от текущей точки в точку (100,200), то rLineTo(100,200) нарисует линию от текущей точки в точку, которая правее текущей на 100 и ниже на 200.

Текст по фигуре

Теперь посмотрим, как можно использовать направление рисования, которое мы задавали в методах addRect и addCircle

Видим четыре текста, которые нарисованы в виде круга. Разберемся, как это сделано.

Добавляем к Path круг методом addCircle, используя направление по часовой — Path.Direction.CW. Далее методом drawTextOnPath рисуем черным цветом текст по контуру path-фигуры. Как видим, текст идет по часовой стрелке. Сам круг при этом не рисуется.

Далее очишаем path и добавляем к нему новый круг, используя направление против часовой Path.Direction.CCW. В нем текст пойдет против часовой стрелки. И синим цветом рисуем и текст и круг.

А теперь рассмотрим параметры drawTextOnPath на зеленой и красной фигурах. Будем использовать тот же path, который нарисовали синим цветом. Только методом offset будем перемещать его на новое место.

У метода drawTextOnPath третий параметр означает длину отступа от старта фигуры. В зеленом круге мы задали этот отступ равным 100. Видно, что по сравнению с синим кругом, текст здесь имеет отступ по окружности от начала.

Четвертый параметр метода drawTextOnPath позволяет указать отступ текста от фигуры. В красном круге мы указали его равным 30. И видим, что текст удален от круга наружу. Если задать отрицательное значение, то текст будет смещен внутрь.

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

На следующем уроке:

— используем Matrix для геометрических преобразований фигур

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

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