Отрисовка линий

Последнее обновление: 14.04.2024

Для отрисовки линий в DrawScope определена функция drawLine():

fun drawLine(
    color: Color,
    start: Offset,
    end: Offset,
    strokeWidth: Float = Stroke.HairlineWidth,
    cap: StrokeCap = Stroke.DefaultCap,
    pathEffect: PathEffect? = null,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Она имеет следующие параметры:

  • color: цвет линии

  • start: начальная точка линии (значение типа Offset)

  • end: конечная точка линии (объект Offset)

  • strokeWidth: ширина линии в Float

  • cap: тип окончания линии в виде значения типа StrokeCap

  • pathEffect: эффект, применяемый к линии

  • alpha: прозрачность, применяемая к цвету линии в виде значения из диапазона от 0.0f до 1.0f

  • colorFilter: цветовой фильтр ColorFilter, который применяется к цвету линии

  • blendMode: алгоритм смешивания, применяемый к цвету

Пример линии:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.geometry.Offset

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Canvas(Modifier.size(300.dp).background(Color.LightGray)) {
                val height = size.height
                val width = size.width
                drawLine(
                    start = Offset(x= 0f, y = 0f),
                    end = Offset(x = width, y = height),
                    color = Color.Blue,
                    strokeWidth = 12.0f
                )
            }
        }
    }
}

Здесь рисуем синию линию шириной в 12 единиц от точки с координатами (x=0, y=0) до точки в правом нижнем углу.

Canvas и отрисовка линии в Jetpack Compose на Kotlin на Android

Стоит учитывать, что для отрисовки линий (как и всех остальных графических примитивов) для определения координат используются не независимые от плотности экрана единицы Dp, а обычные пиксели. Например:

Canvas(Modifier.size(300.dp).background(Color.LightGray)) {
    drawLine(
        start = Offset(x= 0f, y = 0f),
        end = Offset(x = 400f, y = 400f),
        color = Color.Blue,
        strokeWidth = 12.0f
    )
}

Здесь Canvas имеет размер 300х300, а координата крайней точки линии имеет координаты (x=400, y=400). Казалось бы, линия должна уйти за пределы Canvas, но этого не происходит:

Canvas и пиксели в Jetpack Compose на Kotlin на Android

Дело в том, что размер Canvas объявляется в независимых от плотности/устройства пикселях (dp), а координаты для отрисовки указывается в пикселях (px). Независимые от плотности пиксели — это абстрактная величина, которая рассчитывается на основе физической плотности экрана, определяемой в точках на дюйм (dpi). Пиксели, с другой стороны, относятся к реальным физическим пикселям на экране. Чтобы работать исключительно в пикселях (а не в dp), значения dp можно преобразовать в пиксели с помощью функции Px():

Canvas(Modifier.size(300.dp).background(Color.LightGray)) {
    drawLine(
        start = Offset(x= 0f, y = 0f),
        end = Offset(x = 200.dp.toPx(), y = 200.dp.toPx()),
        color = Color.Blue,
        strokeWidth = 12.0f
    )
}

Тип линий

С помощью параметра pathEffect, который представляет значение типа PathEffect, можно настроить тип линии. Чтобы создать пунктирную линию, нам нужно вызвать метод DashPathEffect() объекта PathEffect и передать ему массив чисел с плавающей запятой. Числа с плавающей запятой обозначают интервалы в пикселях внутри линии. Должно быть четное количество интервальных значений, минимум 2 значения. Например:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.PathEffect

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Canvas(Modifier.size(300.dp).background(Color.LightGray)) {
                val height = size.height
                val width = size.width
                drawLine(
                    start = Offset(x= 0f, y = 0f),
                    end = Offset(x = width, y = height),
                    color = Color.Blue,
                    strokeWidth = 12.0f,
                    pathEffect = PathEffect.dashPathEffect(floatArrayOf(30f, 10f, 10f, 10f), phase = 0f)
                )
            }
        }
    }
}

Здесь рисуем линию, которая начинается с длинного штриха в 40 пикселей, после которого идет пробел в 10 пикселей, черточка в 10 пикселей и пробел в 10 пикселей. Далее вся эта комбинация повторяется до конца линии:

Canvas и отрисовка пунктирной линии в Jetpack Compose на Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850