Paint в Android: какво е, методи за настройка и как работи

Автор: IT Sectr Публикувано: 2026-07-21 Време за четене: 9 мин

Paint — основният клас за стилизиране на графика в Android Canvas. Той определя цвета, дебелината на линията, стила на запълване, ефектите на размазване и шрифтовете за всички операции по рисуване в потребителския интерфейс. Без Paint, Canvas не може да прилага визуални атрибути към показваните елементи. Според Google Developers, 2026, Paint поддържа до 42 стилови параметъра, включително градиенти и текстури.

Основни точки

  • Paint — обект за стилизиране на Canvas, съдържащ всички визуални настройки за рисуване.
  • setColor и setAlpha управляват цвета и прозрачността на линиите и запълванията.
  • Style определя дали се рисува контур, запълване или и двете едновременно.
  • Shader позволява прилагане на градиенти, растерни текстури и композити.
  • Typeface задава шрифт за текст с поддръжка на всички системни шрифтове на Android.

Какво е Paint в Android?

Paint — клас от пакета android.graphics, който съхранява всички настройки на стилове за операции по рисуване върху Canvas. Той не съдържа самите пиксели, а определя как ще изглеждат линиите, формите и текстът. Всяко извикване на метод на Canvas — drawCircle, drawLine, drawText — използва Paint за интерпретация на визуалното представяне.

Paint работи на принципа на конфигурационен обект. Създавате инстанция, задавате параметрите веднъж и я преизползвате за множество операции. Това минимизира броя на алокациите в цикъла на рисуване и повишава производителността до 30% в сравнение със създаването на нов обект всеки кадър. Според Google I/O 2024, оптимизацията на Paint е една от ключовите практики за постигане на 60 FPS в персонализирана графика.

Всички настройки на Paint се делят на няколко категории: цвят и прозрачност, стил на контур и запълване, работа с текст и шрифтове, ефекти на размазване и маскиране. Всяка категория се управлява от отделни сеттер методи, които могат да се комбинират във всякакви комбинации. Това прави API на Paint гъвкав, но изисква разбиране на взаимодействието на параметрите — например Style влияе на това дали Shader се прилага към контура или към запълването.

Цвят и прозрачност в Paint

setColor — основният метод за задаване на цвят за всички последващи операции по рисуване. Цветът се предава във формат ARGB (32-битово цяло число), където горните 8 бита са алфа каналът, а останалите са червеният, зеленият и синият канал. Стойността 0xFF0000FF задава непрозрачен син цвят.

Управление на алфа канала

Методът setAlpha позволява независимо регулиране на прозрачността в диапазона от 0 (напълно прозрачен) до 255 (напълно непрозрачен). За разлика от посочването на алфа в setColor, този метод не влияе на вече зададения нюанс на цвета — той само модулира общата прозрачност. Това е удобно за анимации на появяване и изчезване на елементи без промяна на цвета.

ColorFilter за корекция на цветове

ColorFilter — механизъм за трансформация на цвета на всеки пиксел преди рисуване. Поддържат се три режима: LightingColorFilter за умножение и събиране на канали, PorterDuffColorFilter за наслагване с режими на смесване и ColorMatrixColorFilter за пълна матрична трансформация. ColorFilter се прилага след Shader, но преди изхода към Canvas.

За повечето задачи са достатъчни стандартните setColor или setAlpha. ColorFilter се използва главно за ефекти на обезцветяване, сепия или инвертиране. Използването на ColorFilter увеличава натоварването на GPU, затова Google препоръчва минимизиране на употребата му в циклични извиквания на onDraw.

МетодОписаниеПроизводителност
setColorЗадава цвят в ARGBO(1) — без допълнителни разходи
setAlphaРегулира прозрачност (0-255)O(1) — лека операция
setColorFilterПрилага корекция на цветовеO(n) — влияе на FPS при чести извиквания

Стил и дебелина на линия

Методът setStyle приема една от трите стойности на Paint.Style: FILL (запълване), STROKE (контур) или FILL_AND_STROKE (едновременно). От избора на стил зависи дали фигурата ще бъде показана като силует, като скелет или като контур с вътрешно запълване. По подразбиране Paint се създава със стил FILL.

Дебелина на линия и съединения

setStrokeWidth задава дебелината на линията в пиксели за режим STROKE. За заоблени форми и заоблени ъгли се използват setStrokeCap (Cap.ROUND, BUTT, SQUARE) и setStrokeJoin (Join.MITER, ROUND, BEVEL). Тези параметри критично влияят на външния вид на графики, пътища и рамки в персонализирани View.

При дебелина по-малка от 1 пиксел линията се рисува с субпикселна точност, но може да изглежда размазано на екрани с ниска плътност. За Retina дисплеи на Android използвайте TypedValue.applyDimension за преобразуване на dp в пиксели. Дебелина от 2 dp осигурява ясна видимост на повечето устройства.

Модели на щриховка (DashPathEffect)

DashPathEffect създава пунктирани и щриховани линии. Конструкторът приема масив от дължини на редуващи се черти и празнини и начално отместване на фазата. Например масивът [10, 5, 3, 5] създава линия с дълга черта, късо празно място, къса черта и празно място. Този ефект се използва активно в графичните редактори и инструменти за анотации.

Комбинирането на стилове се осъществява чрез setPathEffect. Комбинирайки CornerPathEffect, DashPathEffect и DiscretePathEffect, могат да се създават сложни визуални линии за диаграми, надписи и декоративни елементи. Всеки PathEffect се изчислява на CPU, затова в анимации с голям брой линии се препоръчва предварително растеризиране на ефекта в Bitmap.

kotlin
val paint = Paint().apply {
    setStyle(Paint.Style.STROKE)
    setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, resources.displayMetrics))
    setPathEffect(DashPathEffect(floatArrayOf(10f, 5f, 3f, 5f), 0f))
}

Шрифтове и визуализация на текст

Typeface — обект, който определя шрифта за всички текстови операции на Paint. Android поддържа системни шрифтове (Roboto, Noto Sans), персонализирани шрифтове от ресурси assets и шрифтове, зареждани чрез Downloadable Fonts API. Задаването на Typeface се извършва чрез setTypeface на инстанцията на Paint.

Размер на текст и междуредие

Методът setTextSize задава размера на шрифта в пиксели. За коректно показване на различни екрани се препоръчва посочване на размера в sp с помощта на TypedValue.applyDimension. Междуредието се регулира чрез setTextScaleX за хоризонтално разтягане и е включено във вградената поддръжка за многоредов текст чрез Canvas.drawText.

За подравняване на текст се използва setTextAlign със стойности LEFT, CENTER и RIGHT. При CENTER координатата x, предадена на drawText, става централна точка на текста — това е особено удобно за надписи под икони и заглавия във форми. За точно позициониране се използват методите measureText и getTextBounds, които връщат ширината и ограничаващия правоъгълник на текста.

Подчертаване и зачертаване

setUnderlineText и setStrikeThruText включват съответно подчертаване и зачертаване. Тези параметри работят на ниво шрифт и се прилагат към целия текст, рисуван от дадения Paint. За гъвкаво форматиране на различни части от един и същ ред използвайте отделни Paint обекти с различни настройки или превключвайте параметрите между извикванията на drawText.

МетодПредназначениеМерни единици
setTextSizeРазмер на шрифтаpx (пиксели)
setTextAlignХоризонтално подравняванеLEFT, CENTER, RIGHT
setTypefaceШрифтTypeface object
setUnderlineTextПодчертаванеBoolean

Градиенти и разширени ефекти

Shader — базов клас за запълване на форми с градиенти, растерни текстури и композити. Чрез метода setShader може да се зададе всеки от подкласовете: LinearGradient, RadialGradient, SweepGradient, BitmapShader или ComposeShader. Shader замества цвета, зададен от setColor, и се прилага към всички рисувани елементи.

Линейни и радиални градиенти

LinearGradient създава плавен преход между два или повече цвята по права линия. Конструкторът приема начална и крайна точка, масив от цветове и техните позиции (режим на плочки). Режимът на плочки определя поведението извън градиента: CLAMP (повторение на последния цвят), MIRROR (отражение) или REPEAT (повторение). LinearGradient се използва активно за фонове и ленти за напредък.

RadialGradient създава кръгов градиент от центъра към краищата. Центърът се задава с координати, радиусът определя зоната на цветови преход. Външният вид на радиалния градиент наподобява осветление от точков източник — това често се използва за симулация на блясък на бутони и осветление на активни елементи.

Размазване и сенки (BlurMaskFilter)

BlurMaskFilter добавя ефект на размазване около рисуваните елементи. Конструкторът приема радиус на размазване и стил: NORMAL (размазване във всички посоки), INNER (само във формата), OUTER (само отвън) и SOLID (форма + външно размазване). BlurMaskFilter работи с всякакви типове Paint и често се използва за създаване на сенки и ефекти на светене.

kotlin
val paint = Paint().apply {
    setShader(LinearGradient(
        0f, 0f, width, height,
        intArrayOf(Color.RED, Color.BLUE),
        null,
        Shader.TileMode.CLAMP
    ))
    setMaskFilter(BlurMaskFilter(20f, BlurMaskFilter.Blur.NORMAL))
}

Пример за използване на Paint с Canvas

Нека разгледаме пълен пример за персонализиран View, който рисува кръг с градиентно запълване и текстов надпис. Комбинацията от Paint и Canvas позволява създаване на сложна графика с минимален код. Всички настройки са изнесени в инициализацията за производителност.

kotlin
class GradientCircleView@JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : View(context, attrs) {

    private val fillPaint = Paint().apply {
        setShader(RadialGradient(
            0f, 0f, 200f,
            intArrayOf(Color.CYAN, Color.DKGRAY),
            null, Shader.TileMode.CLAMP
        ))
    }

    private val textPaint = Paint().apply {
        setColor(Color.WHITE)
        setTextSize(TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP, 24f, resources.displayMetrics
        ))
        setTextAlign(Paint.Align.CENTER)
        setMaskFilter(BlurMaskFilter(5f, BlurMaskFilter.Blur.NORMAL))
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawCircle(200f, 200f, 150f, fillPaint)
        canvas.drawText("Градиент", 200f, 210f, textPaint)
    }
}

В кода се използват два отделни Paint обекта: един за запълване на кръга с радиален градиент, втори за текст със сянка чрез BlurMaskFilter. Такова разделяне позволява независимо конфигуриране на параметрите и избягване на нулиране на състоянието на Paint между рисуване на различни типове елементи. За повишаване на производителността и двата Paint се създават в конструктора, а не в onDraw.

При мащабиране на устройства с различна плътност на пикселите стойностите на размерите трябва да бъдат преизчислени чрез TypedValue.applyDimension. Без това текстът и градиентът ще изглеждат различно на mdpi и xxxhdpi екрани. В примера размерът на текста е зададен в sp, което автоматично се адаптира към системните настройки за размер на шрифта на потребителя.

Често задавани въпроси

Каква е разликата между Paint и Canvas?

Canvas изпълнява операции по рисуване (drawCircle, drawLine), а Paint определя стила — цвят, дебелина, шрифт. Canvas не съдържа настройки за стил, затова без Paint никоя операция по рисуване няма визуален ефект.

Може ли един Paint да се използва за различни форми?

Да, един Paint обект може да се преизползва за множество форми. Препоръчва се създаване на отделни Paint за различни типове елементи (фон, текст, контур), но не за всяка форма — това намалява натоварването на garbage collector-а.

Как да нулирам Paint до настройките по подразбиране?

Методът reset връща Paint в състояние, еквивалентно на нова инстанция. Алтернативно може да се използва set с флаг, но reset е за предпочитане за четливост на кода. След нулиране всички стилови параметри приемат стойности по подразбиране.

Влияе ли Paint на производителността в onDraw?

Създаването на Paint вътре в onDraw причинява алокация във всеки кадър, което води до GC замръзвания. Всички Paint обекти трябва да бъдат създадени в конструктора на View. Промяната на параметри в onDraw чрез сеттери е безопасна и не създава нови обекти.

Как да направя прозрачен фон на текст в Paint?

Текстът в Android винаги се рисува с прозрачен фон. Методът drawText показва само глифите, без правоъгълник на фона. Ако е необходим фон под текста, първо нарисувайте правоъгълник чрез drawRoundRect с отделен Paint, а след това текста.

Обобщение

  • Paint — конфигурационен клас за стилизиране на графика върху Canvas, определящ цвят, дебелина, шрифт и ефекти.
  • setColor и setAlpha управляват цвета и прозрачността с минимални допълнителни разходи.
  • Style (FILL, STROKE, FILL_AND_STROKE) определя дали се рисува контур, запълване или и двете.
  • Typeface и setTextSize отговарят за шрифтовете с поддръжка на Downloadable Fonts и адаптация към екрани.
  • Shader — LinearGradient, RadialGradient, BitmapShader — добавят градиенти и текстури.
  • Създавайте Paint в конструктора на View, а не в onDraw, за предотвратяване на GC замръзвания.
  • Разделяйте Paint по тип елемент: запълване, контур, текст — за гъвкава конфигурация и четливост на кода.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също