Для вывода текста на Canvas применяется функция drawText(). Она имеет ряд версий, рассмотрим одну из них:
fun DrawScope.drawText( textMeasurer: TextMeasurer, text: String, topLeft: Offset = Offset.Zero, style: TextStyle = TextStyle.Default, overflow: TextOverflow = TextOverflow.Clip, softWrap: Boolean = true, maxLines: Int = Int.MAX_VALUE, size: Size = Size.Unspecified, blendMode: BlendMode = DrawScope.DefaultBlendMode ): Unit
Эта функция принимает следующие параметры:
textMeasurer
: объект TextMeasurer, который применяется для расположения текста
text
: выводимый текст
topLeft
: определяет смещение текста от верхней левой точки текущей системы координат
style
: стиль заполнения текста
overflow
: указывает, как следует обрабатывать выход текста за границы контейнера
softWrap
: указывает, должен ли текст разрываться при разрывах строк
maxLines
: максимальное количество строк
size
: размер прямоугольной области, в которую вписывается текст
blendMode
: алгоритм смешивания, применяемый к цвету текста
Еще одна версия:
fun DrawScope.drawText( textLayoutResult: TextLayoutResult, color: Color = Color.Unspecified, topLeft: Offset = Offset.Zero, alpha: Float = Float.NaN, shadow: Shadow? = null, textDecoration: TextDecoration? = null, drawStyle: DrawStyle? = null, blendMode: BlendMode = DrawScope.DefaultBlendMode ): Unit
Эта версия функции принимает следующие параметры:
textLayoutResult
: параметры расположения текста
color
: цвет пути
topLeft
: определяет смещение текста от верхней левой точки текущей системы координат
alpha
: прозрачность, применяемая к тексту
shadow
: параметры тени текста
textDecoration
: декорации текста (например, подчеркивание)
drawStyle
: стиль заполнения текста
blendMode
: алгоритм смешивания, применяемый к цвету текста
Для установки расположения текста применяется объект TextMeasurer, который применяется для расчета размера текста в зависимости от семейства и размера шрифта. Для получения объекта TextMeasurer применяется функция rememberTextMeasurer():
val textMeasurer = rememberTextMeasurer()
Получив объект TextMeasurer, его можно передать его в функцию drawText()
вместе с текстом, который нужно отрисовать:
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.layout.fillMaxSize import androidx.compose.ui.Modifier import androidx.compose.ui.text.drawText import androidx.compose.ui.text.rememberTextMeasurer class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val textMeasurer = rememberTextMeasurer() Canvas(Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello METANIT.COM") } } } }
Однако по умолчанию получается довольно маленький текст. И с помощью TextMeasurer мы можем настроить его параметры с помощью функции TextMeasurer.measure()
:
fun measure( text: String, style: TextStyle = TextStyle.Default, overflow: TextOverflow = TextOverflow.Clip, softWrap: Boolean = true, maxLines: Int = Int.MAX_VALUE, constraints: Constraints = Constraints(), layoutDirection: LayoutDirection = this.defaultLayoutDirection, density: Density = this.defaultDensity, fontFamilyResolver: FontFamily.Resolver = this.defaultFontFamilyResolver, skipCache: Boolean = false ): TextLayoutResult
Эта функция позволяет задать текст, его стиль, семейство шрифтов и т.д. Например:
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.layout.fillMaxSize import androidx.compose.ui.Modifier import androidx.compose.ui.text.drawText import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val textMeasurer = rememberTextMeasurer() val textLayoutResult = textMeasurer.measure( text = "Hello METANIT.COM", style = TextStyle(fontSize = 28.sp) ) Canvas(Modifier.fillMaxSize()) { drawText(textLayoutResult) } } } }
В данном случае для шрифта задается высота в 28 единиц:
Кроме обычного текста drawText()
позволяет выводить аннотированные строки с более сложным форматированием отдельных сегментов текста. Для создагния аннотированных строк применяется
функция buildAnnotatedString(). Подробнее про аннотированные строки рассказывалось в статье Аннотированные строки.
Здесь же рассмотрим их вывод на Canvas:
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.layout.fillMaxSize import androidx.compose.ui.Modifier import androidx.compose.ui.text.drawText import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val textMeasurer = rememberTextMeasurer() val annotatedText = buildAnnotatedString { withStyle( style = SpanStyle( fontSize = 38.sp, fontWeight = FontWeight.ExtraBold, color = Color.DarkGray ) ) { append("Hello ") } withStyle( style = SpanStyle( fontSize = 40.sp, fontWeight = FontWeight.ExtraBold, color = Color.Blue ) ) { append("METANIT.COM") } } Canvas(modifier = Modifier.fillMaxSize()) { drawText(textMeasurer, annotatedText) } } } }
В данном случае определяется два сегмента текста с разным форматированием: