Для отрисовки линий в 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) до точки в правом нижнем углу.
Стоит учитывать, что для отрисовки линий (как и всех остальных графических примитивов) для определения координат используются не независимые от плотности экрана единицы 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 объявляется в независимых от плотности/устройства пикселях (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 пикселей. Далее вся эта комбинация повторяется до конца линии: