Text is used to display Text control, its underlying implementation is through Cavans drawText to achieve. Now let’s talk about how to use it.

A: Text structure source code

@Composable
fun Text(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    onTextLayout: (TextLayoutResult) - >Unit = {},
    style: TextStyle = AmbientTextStyle.current
){... }Copy the code
  • Text is displayed text
  • Modifier, you can click the link to view the details of the article modifier
  • Color is the color
  • FontSize specifies the fontSize
  • FontStyle (italic, for example)
  • Font style for fontWeight (such as bold)
  • FontFamily handles fonts (e.g., setting song Style, etc.)
  • LetterSpacing The spacing between each character
  • TextDecoration text decoration, such as textDecoration. Underline Underline, such as textDecoration. LineThrough Central Line
  • TextAlign Sets the text alignment alignment
  • LineHeight sets the lineHeight
  • Overflow When text overflows, as in… Settings are displayed at the end
  • SoftWrap states whether text should be broken at a newline, which defaults to true
  • MaxLines Maximum number of lines
  • onTextLayout
  • Style is TextStyle, TextStyle support

Two: display text

The most basic way to display Text is to use a Text composable that takes a String:

@Composable
fun SimpleText(a) {
  Text("Hello World")}Copy the code

1.2 Displaying text in resources

We recommend that you use string resources instead of hard-coding Text values, because with string resources you can share the same string with Android views and prepare your application for internationalization

@Composable
fun StringResourceText(a) {
  Text(stringResource(R.string.hello_world))
}
Copy the code

Three: set the text style

3.1 Change the text color

@Composable
fun BlueText(a) {
  Text("Hello World", color = Color.Blue)
}
Copy the code

3.2 Changing font size

@Composable
fun BigText(a) {
  Text("Hello World", fontSize = 30.sp)
}
Copy the code

3.3 Setting italics

@Composable
fun ItalicText(a) {
  // Set italics
  Text("Hello World", fontStyle = FontStyle.Italic)
}
Copy the code

3.4 Setting bold

@Composable
fun ItalicText(a) {
  // Set bold
  Text("Hello World2", fontWeight = FontWeight.Bold)
}
Copy the code

3.5 Text Alignment

@Preview(showBackground = true)
@Composable
fun CenterText(a) {
    Text("Hello World", textAlign = TextAlign.Center,
                modifier = Modifier.width(150.dp))
}
Copy the code



By default, Text selects natural Text alignment based on its content value:

  • For Text written from left to right, such as Latin, Greek, or Korean, align toward the left edge of the Text container
  • For Text written from right to left, such as Arabic or Hebrew, align toward the right edge of the Text container

If you want to manually set the Text alignment for Text composables, it is best to use textalign.start and textalign.end respectively (instead of textalign.left and textalign.right), This allows the system to parse your Settings to align to the right edge of Text, depending on the preferred Text orientation for the specific language

3.6 Handling Fonts

Text has a fontFamily parameter that sets the font to use in composable entries. By default, Serif, Sans Serif, equal width, and Cursive are added:

@Composable
fun DifferentFonts(a) {
    Column {
        Text("Hello World", fontFamily = FontFamily.Serif)
        Text("Hello World", fontFamily = FontFamily.SansSerif)
    }
}
Copy the code



Of course, you can still use your own font file, which is still under res-fontThen you need to define a font cluster, which is the Compose recommended use because it can contain different word weights

val firaSansFamily = FontFamily(
        Font(R.font.firasans_light, FontWeight.Light),
        Font(R.font.firasans_regular, FontWeight.Normal),
        Font(R.font.firasans_italic, FontWeight.Normal, FontStyle.Italic),
        Font(R.font.firasans_medium, FontWeight.Medium),
        Font(R.font.firasans_bold, FontWeight.Bold)
)
Copy the code

Finally, you can pass this fontFamily to the Text composable. Since fontFamily can contain different thicknesses, you can manually set fontWeight to select the appropriate thicknesses for your text:

Column { Text(... , fontFamily = firaSansFamily, fontWeight = FontWeight.Light) Text(... , fontFamily = firaSansFamily, fontWeight = FontWeight.Normal) Text(... , fontFamily = firaSansFamily, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Italic) Text(... , fontFamily = firaSansFamily, fontWeight = FontWeight.Medium) Text(... , fontFamily = firaSansFamily, fontWeight = FontWeight.Bold) }Copy the code

3.7 Text Decoration

@Preview()
@Composable
fun textTest(a){
    Column() {
        Text(text = stringResource(id = R.string.app_name),textDecoration = TextDecoration.LineThrough)
    }
}
Copy the code

3.8 line height

@Preview()
@Composable
fun textTest(a){
    Column() {
        Text(text = stringResource(id = R.string.app_name),lineHeight = 15.sp)
    }
}
Copy the code

3.9 Character Spacing

@Preview()
@Composable
fun textTest(a){
    Column() {
        Text(text = stringResource(id = R.string.app_name),letterSpacing = 3.sp)
    }
}
Copy the code

3.10 Maxline: Sets the maximum number of lines

@Composable
@Composable
fun LongText(a) {
    Text("hello ".repeat(50), maxLines = 2)}Copy the code

3.11 Overflow Sets text overflow

When limiting long text, you may need to specify text overflow, which is displayed only if the displayed text is truncated. To specify textOverflow, set the textOverflow parameter as follows:

@Composable
fun OverflowedText(a) {
    // Textoverflow. Ellipsis is the end... TextOverflow. The Clip is intercepted
    Text("Hello Compose ".repeat(50), maxLines = 2, overflow = TextOverflow.Ellipsis)
}
Copy the code

3.12 TextStyle style

Let’s take a look, the last parameter of Text style, is actually TextStyle, TextStyle is mainly Text style support, let’s take a look at TextStyle source

@Immutable
data class TextStyle(
    val color: Color = Color.Unspecified,
    val fontSize: TextUnit = TextUnit.Unspecified,
    val fontWeight: FontWeight? = null.val fontStyle: FontStyle? = null.val fontSynthesis: FontSynthesis? = null.val fontFamily: FontFamily? = null.val fontFeatureSettings: String? = null.val letterSpacing: TextUnit = TextUnit.Unspecified,
    val baselineShift: BaselineShift? = null.val textGeometricTransform: TextGeometricTransform? = null.val localeList: LocaleList? = null.val background: Color = Color.Unspecified,
    val textDecoration: TextDecoration? = null.val shadow: Shadow? = null.val textAlign: TextAlign? = null.val textDirection: TextDirection? = null.val lineHeight: TextUnit = TextUnit.Unspecified,
    val textIndent: TextIndent? = null
){
    ...
}
Copy the code
  • Color is also used to set the text color
  • FontSize fontSize
  • FontWeight sets font styles such as bold
  • FontStyle sets font styles such as italics
  • FontFamily sets the font. Such as song typeface
  • LetterSpacing sets character spacing
  • Background Sets the background color
  • TextDecoration Sets decoration, such as underline, underline
  • TextAlign sets the alignment
  • TextDirection sets the textDirection, such as left to right or right to left
  • LineHeight sets the lineHeight
// Since we have already introduced these attributes, we agree to write a simple sample
@Preview()
@Composable
fun textStyleTest(a){
    Column {
        Text(text = stringResource(id = R.string.app_name),style = TextStyle(
                color = Color.Blue,fontSize = 13.sp,fontWeight=FontWeight.Bold
                ,fontStyle = FontStyle.Italic,fontFamily= FontFamily.Cursive
                ,letterSpacing= TextUnit.Companion.Em(1f),background = Color.Yellow
                ,textDecoration = TextDecoration.Underline,textAlign = TextAlign.Center,
                textDirection = TextDirection.ContentOrRtl,lineHeight = TextUnit.Companion.Em(13f)))}}Copy the code
  • Shadow Set shadow (set shadow for text)
@Preview()
@Composable
fun textStyleTest(a){
    Column {
        Text(text = stringResource(id = R.string.app_name),style = TextStyle(
               shadow = Shadow(
                    color = Color.Red,blurRadius = 3f,offset = Offset(3))))}}Copy the code
  • FontSynthesis there are four main types of fontSynthesis
enum class FontSynthesis {
    /** * Turn off font composition. If there are no bold or slanted faces in [FontFamily], they are not synthesized */
    None,

    /** * If there is no bold font in [FontFamily], only bold font is synthesized. No slant font composition. * /
    Weight,

    /** * If there is no bold font in [FontFamily], only bold font is synthesized. No slant font composition. * /
    Style,

    /** * If [FontFamily] does not have a bold or slanted font, the system combines the two fonts */
    All;

    internal val isWeightOn: Boolean
        get() = this == All || this == Weight

    internal val isStyleOn: Boolean
        get() = this == All || this == Style
}
Copy the code
  • The two lattice parameter scaleX represents the horizontal scale of text and skewX represents the clipping tilt of text in the horizontal direction.
@Immutable
data class TextGeometricTransform(
    val scaleX: Float = 1.0 f.val skewX: Float = 0f) {... }Copy the code

For example

// For example
@Preview()
@Composable
fun textStyleTest(a){
    Column {
        Text(text = "Hello Android",style = TextStyle(
                textGeometricTransform = TextGeometricTransform(2f.2f)))}}Copy the code
  • fontFeatureSettings
  • You can set three values to baselineShift. BaselineShift.BaselineShift,BaselineShift.Subscript,BaselineShift.NONE
// For example
@Preview()
@Composable
fun textStyleTest(a){
    Column {
        Text(text = "Hello Android",style = TextStyle(
                baselineShift = BaselineShift.Subscript
        ))
    }
}
Copy the code
  • localeList
  • TextIndent Specifies the indentation of the paragraph. FirstLine is how much to indent the firstLine, and restLine is how much to indent each line except the firstLine
data class TextIndent(
    val firstLine: TextUnit = 0.sp,
    val restLine: TextUnit = 0.sp
) {
   ...
}

@Preview()
@Composable
fun textStyleTest(a){
    Column {
        Text(text = stringResource(id = R.string.app_name),style = TextStyle(
                textIndent = TextIndent(40.sp, 20.sp)
        ))
    }
}
Copy the code

3.13 Text contains a variety of styles

When there are multiple styles in the same text, the traditional method for setting different styles is Span, and Compose uses AnnotatedString, which can be annotated with any annotation style. AnnotatedString is a data class that contains:

  • A Text value
  • A SpanStyleRange List, equivalent to the inline styles of position ranges within text values
  • A List that goes by ParagraphStyleRange, which specifies text alignment, text direction, line height, and text indentation style

TextStyle is used for Text composable items, while SpanStyle and ParagraphStyle are used for AnnotatedString.

The difference between SpanStyle and ParagraphStyle is that ParagraphStyle applies to an entire paragraph, while SpanStyle can be applied at the character level. Once you mark one part of text with ParagraphStyle, that part is separated from the rest, just as there are line breaks at the beginning and end

@Preview()
@Composable
fun textTest(a){
    Column() {
        androidx.compose.material.Text(text = AnnotatedString(){
            withStyle(style = SpanStyle(color = Color.Blue)){
                append("H")
            }
            append("ello ")
            withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)){
                append("W")
            }
            append("orld")}}}Copy the code

We can set paragraph styles the same way:

@Preview()
@Composable
fun textTest2(a){
    Column() {
        androidx.compose.material.Text(text = AnnotatedString(){
            withStyle(style = ParagraphStyle(lineHeight = 30.sp)) {
                withStyle(style = SpanStyle(color = Color.Blue)) {
                    append("Hello\n")
                }
                withStyle(style = SpanStyle(fontWeight = FontWeight.Bold,
                        color = Color.Red)) {
                    append("World\n")
                }
                append("Compose")}})}}Copy the code

Three: user interaction

3.1 Selecting Text

By default, composables are not selectable, which means that users cannot select and copy text from your application by default. To enable text selection, encapsulate text elements with SelectionContainer composables:

@Composable
fun SelectableText(a) {
    SelectionContainer {
        Text("This text is selectable")}}Copy the code

You may want to disable selection for a specific part of the selectable area. To do this, you need to use the DisableSelection combinable to encapsulate the non-selectable part:

@Composable
fun PartiallySelectableText(a) {
    SelectionContainer {
        Column {
            Text("This text is selectable")
            Text("This one too")
            Text("This one as well")
            DisableSelection {
                Text("But not this one")
                Text("Neither this one")
            }
            Text("But again, you can select this one")
            Text("And this one too")}}}Copy the code

3.2 Obtain the position of the click text

To listen for the number of clicks on Text, you can add the Clickable modifier. However, if you want to get the click position within the Text composable, you need to switch to ClickableText in cases where different operations are performed on different parts of the Text.

@Composable
fun SimpleClickableText(a) {
    ClickableText(
        text = AnnotatedString("Click Me"),
        onClick = { offset ->
            Log.d("ClickableText"."$offset -th character is clicked.")})}Copy the code

3.3 Click annotations

When a user clicks on a Text combinable, you might want to append additional information to a part of the Text value, such as a web address that can be opened in the browser to a particular word. To do this, you need to attach an annotation that takes a token (String), an item (String), and a literal range as parameters. In AnnotatedString, these annotations can be filtered by their markup or literal range. The following is an example:

@Preview()
@Composable
fun textTest3(a){
    val annotatedText = AnnotatedString {
        append("Click ")

        // We attach this *URL* annotation to the following content
        // until `pop()` is called
        pushStringAnnotation(tag = "URL".annotation = "https://developer.android.com")
        withStyle(style = SpanStyle(color = Color.Blue,
                fontWeight = FontWeight.Bold)) {
            append("here")
        }

        pop()
    }

    ClickableText(
            text = annotatedText,
            onClick = { offset ->
                // We check if there is an *URL* annotation attached to the text
                // at the clicked position
                annotatedText.getStringAnnotations(tag = "URL", start = offset, end = offset) .firstOrNull()? .let {annotation ->
                            // If yes, we log its value
                            Log.d("Clicked URL".annotation.item)
                        }
            }
    )
}
Copy the code