Make writing a habit together! This is the fifth day of my participation in the “Gold Digging Day New Plan · April More Text Challenge” click to see the details of the event.

Android TextView is the Text control used in Compose

Text display

Speaking of text display, let’s open up the Compose project we created earlier and see the code below:

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}
Copy the code

What you see is Text display using Text(). However, Google officially advised us to use string resources to facilitate our future international adaptation. So how do we use string resources?

@Composable
fun TestText(){
    Text(text = stringResource(id = R.string.app_name))
}
Copy the code

Using stringResource in Compose allows you to read string resources directly. Now we need to Preview the effect. We mentioned the Preview annotation earlier, so let’s use it to view the Preview:

@Preview(showBackground = true, heightDp = 100, widthDp = 200)
@Composable
fun TestTextPreview() {
    TestText()
}
Copy the code

Let me see the effect:

If we don’t need any other Settings, we can just use Text as above. If we need other Settings, how can we achieve some Text effects? So we still have to look at the source code:

@composable fun Text(Text: String, modifier: modifier = modifier,// modifier color: Composable fun Text(Text: String, modifier: modifier = modifier,// Unspecified,// The text Color fontSize: TextUnit = TextUnit.Unspecified,// The size fontStyle: fontStyle? = null,// font style fontWeight: fontWeight? = null,// fontFamily: fontFamily? Unspecified = null,// letterSpacing: TextUnit = TextUnit.Unspecified,// Character spacing textDecoration: textDecoration? = null,// The decoration to draw on the text (such as underscores) textAlign: textAlign? Unspecified,// lineHeight: TextUnit = TextUnit.Unspecified,// lineHeight: TextOverflow = textoverflow. Clip,// How visual overflow should be handled in softWrap: Boolean = true,// Whether text should be broken at newlines maxLines: Int = Int.MAX_VALUE,// Max lines onTextLayout: (TextLayoutResult) -> Unit = {},// Callback style when calculating new text layout: TextStyle = localtextstyle.current // TextStyle configuration, such as color font line height, etc.)Copy the code

We see that only text is mandatory, and all other parameters have default values.

Setting text Styles

1. Text color

@Composable
fun TestText() {
    Text(
        text = stringResource(id = R.string.app_name),
        color = Color.Blue,
    )
}
Copy the code

The code is very simple, we just set the font color of the text to blue, and here is the preview:

2. Font size

@Composable
fun TestText() {
    Text(
        text = stringResource(id = R.string.app_name),
        color = Color.Blue,
        fontSize = 25.sp
    )
}
Copy the code

The fontSize parameter fontSize is of type TextUnit. Sp, which is the extension function Compose wrote for us. Int, Float, Double can all be used this way

@Stable
val Float.sp: TextUnit get() = pack(UNIT_TYPE_SP, this)

@Stable
val Double.sp: TextUnit get() = pack(UNIT_TYPE_SP, this.toFloat())

@Stable
val Int.sp: TextUnit get() = pack(UNIT_TYPE_SP, this.toFloat())
Copy the code

3. Set italics

@Composable
fun TestText() {
    Text(
        text = stringResource(id = R.string.app_name),
        color = Color.Blue,
        fontSize = 25.sp,
        fontStyle = FontStyle.Italic,
    )
}
Copy the code

FontStyle:

inline class FontStyle(val value: Int) { override fun toString(): String { return when (this) { Normal -> "Normal" Italic -> "Italic" else -> "Invalid" } } companion object { /** Use the  upright glyphs */ val Normal = FontStyle(0) /** Use glyphs designed for slanting */ val Italic = FontStyle(1) /** Returns a list of possible values of [FontStyle]. */ fun values(): List<FontStyle> = listOf(Normal, Italic) } }Copy the code

The code is simple, just an enumerated class with two arguments: Normal and Italic

4. Set the font size

Font size is set with FontWeight, let’s look at FontWeight source

@Immutable class FontWeight(val weight: Int) : Comparable<FontWeight> { companion object { @Stable val W100 = FontWeight(100) @Stable val W200 = FontWeight(200) @Stable val W300 = FontWeight(300) @Stable val W400 = FontWeight(400) @Stable val W500 = FontWeight(500) @Stable val W600 = FontWeight(600) @Stable val W700 = FontWeight(700) @Stable val W800 = FontWeight(800) @Stable val W900 = FontWeight(900) @Stable val Thin = W100 @Stable val ExtraLight = W200 @Stable val Light = W300 @Stable val Normal = W400  @Stable val Medium = W500 @Stable val SemiBold = W600 @Stable val Bold = W700 @Stable val ExtraBold = W800 @Stable val Black = W900 internal val values: List<FontWeight> = listOf( W100, W200, W300, W400, W500, W600, W700, W800, W900 ) } init { require(weight in 1.. 1000) { "Font weight can be in range [1, 1000]. Current value: $weight" } } }Copy the code

The code has a built-in thickness effect from W100 to W900, depending on the actual situation which bold to use. FontWeight has a constructor that takes parameters so we can customize the weight. There are good ones built in, as well as the familiar Bold and Normal

@Composable
fun TestText() {
    Text(
        text = stringResource(id = R.string.app_name),
        color = Color.Blue,
        fontSize = 25.sp,
        fontStyle = FontStyle.Italic,
        fontWeight = FontWeight.Bold
    )
}
Copy the code

As stated above, we can also customize the value of thickness:

@Composable
fun TestText() {
    Text(
        text = stringResource(id = R.string.app_name),
        color = Color.Blue,
        fontSize = 25.sp,
        fontStyle = FontStyle.Italic,
        fontWeight = FontWeight(10)
    )
}
Copy the code

This is what happens when we change the weight value to 10

5. Set the font

The font is modified using the fontFamily parameter, which sets the font to use. As usual, look at the source code first:

Sealed class FontFamily(Val canLoadSynchronously: Boolean) {Companion object {// Default font val Default: SystemFontFamily = DefaultFontFamily() // Font with low contrast and flat stroke endings Val SansSerif = GenericFontFamily("sans-serif") // Scripts Val Monospace = GenericFontFamily(" Monospace ") // Cursive, handwritten fonts val Cursive = GenericFontFamily("cursive") } }Copy the code

The system provides 5 fonts by default. Let’s use all 5 fonts to see the effect:

@Composable
fun TestText() {
    Column {
        Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Default)
        Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.SansSerif)
        Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Serif)
        Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Monospace)
        Text(text = stringResource(id = R.string.app_name), fontFamily = FontFamily.Cursive)
    }
}
Copy the code

In addition to the fonts given by the system, we can also add custom fonts and fonts. First we will talk about the font files in the RES /font folder.

After placing the font, we need to define fontFamily according to the font file:

val customFamily = FontFamily(
    Font(R.font.family_normal, FontWeight.Normal),
    Font(R.font.family_bold, FontWeight.Bold),
)
Copy the code

We can then pass this fontFamily to Text to use:

Text(text = stringResource(id = R.string.app_name), fontFamily = customFamily, fontWeight = FontWeight.Bold)
Copy the code

6. Set the character spacing

The letterSpacing parameter of Text is used to set character spacing. The parameter type and the setting font size are the same:

@Composable
fun TestText() {
    Text(
        text = stringResource(id = R.string.app_name),
        letterSpacing = 5.sp
    )
}
Copy the code

Not only In English, but also in Chinese

7. Set text decorations

TextDecoration is used to set the textDecoration parameter, textDecoration let me take a look at the source code:

@Immutable class TextDecoration internal constructor(val mask: Int) { companion object { @Stable val None: TextDecoration = TextDecoration(0x0) // Underline @stable val Underline: @stable Val LineThrough: TextDecoration = TextDecoration(0x2)}}Copy the code

Let’s see how text decoration works. Okay?

@composable fun TestText() {Column {Text = "Composable fun TestText ", TextDecoration = textDecoration.None) textDecoration = textDecoration.None) textDecoration = textDecoration. TextDecoration = textDecoration. Underline) Text (Text = "farmers liny small yards," textDecoration = textDecoration. LineThrough)}}Copy the code

8. Text alignment

The textAlign parameter is used to set the alignment of text. The type of the argument is TextAlign.

inline class TextAlign internal constructor(internal val value: Int) {
    companion object {
        val Left = TextAlign(1)
        val Right = TextAlign(2)
        val Center = TextAlign(3)
        val Justify = TextAlign(4)
        val Start = TextAlign(5)
        val End = TextAlign(6)
    }
}
Copy the code

Let’s take centering as an example:

Text(Text = "mU feng ", textAlign = Textalign.center, Modifier = Modifier.width(200.dp))Copy the code

9. Set the row height

The argument used to set the lineHeight is lineHeight, and the argument type is TextUnit.

Text(Text = "lineHeight = 35.sp ", lineHeight = 35.sp)Copy the code

10. Text overflow

Handle TextOverflow cases using overflow and TextOverflow. Direct look at the source code:

inline class TextOverflow internal constructor(internal val value: Int) { override fun toString(): String { return when (this) { Clip -> "Clip" Ellipsis -> "Ellipsis" Visible -> "Visible" else -> "Invalid" } } companion  object { val Clip = TextOverflow(1) val Ellipsis = TextOverflow(2) val Visible = TextOverflow(3) } }Copy the code
Text(Text = "overflow = textoverflow. Ellipsis, maxLines = 2")Copy the code

11. Rich text display in text

This is often used at the bottom of the login or registration page to agree privacy permissions.

To do this, we need the AnnotatedString class. First look at the source code:

@Immutable
class AnnotatedString internal constructor(
    val text: String,
    val spanStyles: List<Range<SpanStyle>> = emptyList(),
    val paragraphStyles: List<Range<ParagraphStyle>> = emptyList(),
    internal val annotations: List<Range<out Any>> = emptyList()
)
Copy the code
  • Text: Indicates the text content
  • SpanStyles: Used to specify a SpanStyle for a specific part of the text
  • ParagraphStyles: Used to specify text alignment, text direction, line height, and text indentation styles.

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.

Let’s look at the specific use:

@Composable fun TestText() { Text(buildAnnotatedString { withStyle(style = SpanStyle(color = Color.Gray, FontSize = 14.sp)){append(" read and agree ")} withStyle(style = SpanStyle(color = color.green, FontSize = 14.sp)){append(" user ")} withStyle(style = SpanStyle(color = color.gray, FontSize = 14.sp)){append(" and ")} withStyle(style = SpanStyle(color = color.green, FontSize = 14.sp)){withStyle(style = SpanStyle(color = color.gray, fontSize = 14.sp)){append(" )}}}Copy the code

Set text selection

Fine-grained interaction of Text is supported in Compose, and Text selection is now more flexible and can be selected across a variety of composable item layouts. By default, composable items are not selectable, which means that the user cannot select and copy text by default. To enable text selection, encapsulate text elements with SelectionContainer composables:

@composable fun TestText() {mysqli = mysql.fillmaxSize ()) {Composable fun TestText() {mysqli = mysql.fillmaxSize ()) {Composable fun TestText() {mysqli = mysql.fillmaxSize (); I can choose ", fontSize = 35.sp)}}Copy the code

This one requires a long press, we can’t preview the effect, we can only run to see the effect:

For example, in a paragraph, we do not want the user to select a part of the text, how to do this? Here we can use the DisableSelection combinable to encapsulate the non-selectable part:

@composable fun TestText() {mysqli = mysql.fillmaxSize ()) {Column {Text(Composable fun TestText) Text(Text = "") DisableSelection {Text(Text =" ")}}}Copy the code

We can see thatWhite hair floating green waterThis is the unselected state

The last

If you have a different opinion, please leave a comment below. I am Mu Xiaofeng, a shandong native who loves learning and programming. (The content of this article is only for learning reference, if there is infringement, I am very sorry, please contact the author immediately to delete.)