Jetpack Compose(一):Text

本文介绍了JetpackCompose中的Text组件,详细讲解了其各种属性如文本内容、颜色、大小、字体样式等,并提供了代码示例和属性应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

自从去年参加 Android 官方发起了 Jetpack Compose 的推广活动:Jetpack Compose 开发者挑战赛以后,再未系统的学习过 Jetpack Compose 的内容,一晃一年就过去了,官方版本已经更新至稳定版 本1.1.1,Alpha 版本 1.2.0-alpha04

从今天开始,继续自学 Jetpack Compose,就从文本 Text 开始吧,用不用得上再说。

Text

属性

@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 = LocalTextStyle.current
) 
属性含义
text文本内容
modifer修饰器
color文本颜色
fontSize文本大小
fontStyle字体样式
fontWeight文本粗细
fontFamily文本字体
letterSpacing文字间隔
textDecoration文本装饰
textAlign文本对齐方式
lineHeight行高
overflow文本溢出处理方式
softWrap自动换行
maxLines最大显示行数
onTextLayout计算布局回调函数
style文本样式

另外还有一个 Text 函数,大同小异,多出两个属性。

@Composable
fun Text(
    text: AnnotatedString,
    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,
    inlineContent: Map<String, InlineTextContent> = mapOf(),
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
)
属性含义
textAnnotatedString 类型,可显示内容更加丰富
inlineContent内联内容

属性示例

color

val colors = listOf(Purple200, Purple500, Purple700)
items(3) {
    Text(text = "假如我是一只鸟,", color = colors[it])
}

color

fontSize

items(3) {
    Text(text = "我也应该用嘶哑的喉咙歌唱,", fontSize = (12 * (it + 1)).sp)
}

fontSize

fontStyle

items(2) {
    Text(text = "这被暴风雨所打击着的土地,", fontStyle = FontStyle.values()[it])
}

fontStyle

fontWeight

items(9) {
    Text(text = "这永远汹涌着我们的悲愤的河流,", fontWeight = FontWeight(100 * (it + 1)))
}

fontWeight

fontFamily

@Composable
fun FontFamilySansSerifSample() {
    Text(
        text = "Demo Text sans-serif",
        fontFamily = FontFamily.SansSerif
    )
}

@Composable
fun FontFamilySerifSample() {
    Text(
        text = "Demo Text serif",
        fontFamily = FontFamily.Serif
    )
}

@Composable
fun FontFamilyMonospaceSample() {
    Text(
        text = "Demo Text monospace",
        fontFamily = FontFamily.Monospace
    )
}

@Composable
fun FontFamilyCursiveSample() {
    Text(
        text = "Demo Text cursive",
        fontFamily = FontFamily.Cursive
    )
}

@Composable
fun CustomFontFamilySample() {
    val fontFamily = FontFamily(
        Font(
            resId = R.font.myfont_regular,
            weight = FontWeight.W400,
            style = FontStyle.Normal
        ),
        Font(
            resId = R.font.myfont_italic,
            weight = FontWeight.W400,
            style = FontStyle.Italic
        )
    )
    Text(text = "Demo Text", fontFamily = fontFamily)
}

@Composable
fun FontFamilySynthesisSample() {
    // The font family contains a single font, with normal weight
    val fontFamily = FontFamily(
        Font(resId = R.font.myfont_regular, weight = FontWeight.Normal)
    )
    // Configuring the Text composable to be bold
    // Using FontSynthesis.Weight to have the system render the font bold my making the glyphs
    // thicker
    Text(
        text = "Demo Text",
        style = TextStyle(
            fontFamily = fontFamily,
            fontWeight = FontWeight.Bold,
            fontSynthesis = FontSynthesis.Weight
        )
    )
}

fontFamily

letterSpacing

items(5) {
    Text(text = "和那来自林间的无比温柔的黎明,", letterSpacing = (it * 5).sp)
}

letterSpacing

textDecoration

@Composable
fun TextDecorationLineThroughSample() {
    Text(
        text = "Demo Text",
        textDecoration = TextDecoration.LineThrough
    )
}

@Composable
fun TextDecorationUnderlineSample() {
    Text(
        text = "Demo Text",
        textDecoration = TextDecoration.Underline
    )
}

@Composable
fun TextDecorationCombinedSample() {
    Text(
        text = "Demo Text",
        textDecoration = TextDecoration.Underline + TextDecoration.LineThrough
    )
}

textDecoration

textAlign

val textAligns = listOf(
    TextAlign.Left,
    TextAlign.Right,
    TextAlign.Center,
    TextAlign.Justify,
    TextAlign.Start,
    TextAlign.End
)
items(6) {
    Text(
        modifier = Modifier.fillMaxWidth(),
        text = "——连羽毛也腐烂在土地里面,",
        textAlign = textAligns[it]
    )
}

textAlign

lineHeight

items(4) {
    Text(
        modifier = Modifier.fillMaxWidth(),
        text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
        lineHeight = (20 * (it + 1)).sp
    )
}

lineHeight

overflow

@Composable
fun TextOverflowClipSample() {
    Text(
        text = "Hello ".repeat(2),
        modifier = Modifier.size(100.dp, 70.dp).background(Color.Cyan),
        fontSize = 35.sp,
        overflow = TextOverflow.Clip
    )
}

@Composable
fun TextOverflowEllipsisSample() {
    Text(
        text = "Hello ".repeat(2),
        modifier = Modifier.width(100.dp).background(Color.Cyan),
        fontSize = 35.sp,
        overflow = TextOverflow.Ellipsis,
        maxLines = 1
    )
}

@Composable
fun TextOverflowVisibleFixedSizeSample() {
    val background = remember { mutableStateOf(Color.Cyan) }
    Box(modifier = Modifier.size(100.dp, 100.dp)) {
        Text(
            text = "Hello ".repeat(2),
            modifier = Modifier.size(100.dp, 70.dp)
                .background(background.value)
                .clickable {
                    background.value = if (background.value == Color.Cyan) {
                        Color.Gray
                    } else {
                        Color.Cyan
                    }
                },
            fontSize = 35.sp,
            overflow = TextOverflow.Visible
        )
    }
}

@Composable
fun TextOverflowVisibleMinHeightSample() {
    val background = remember { mutableStateOf(Color.Cyan) }
    val count = remember { mutableStateOf(1) }
    Box(modifier = Modifier.size(100.dp, 100.dp)) {
        Text(
            text = "Hello".repeat(count.value),
            modifier = Modifier.width(100.dp).heightIn(min = 70.dp)
                .background(background.value)
                .clickable {
                    background.value =
                        if (background.value == Color.Cyan) Color.Gray else Color.Cyan
                    count.value = if (count.value == 1) 2 else 1
                },
            fontSize = 35.sp,
            overflow = TextOverflow.Visible
        )
    }
}

overflow

softWrap

items(2) {
    Text(
        modifier = Modifier.fillMaxWidth(),
        text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
        softWrap = it == 1
    )
}

softWrap

maxLines

item {
    Text(
        text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " +
                "incididunt ut labore et dolore magna aliqua.\nUt enim ad minim veniam, quis " +
                "nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
        maxLines = 2
    )
}

maxLines

onTextLayout

item {
    Text(
        modifier = Modifier.fillMaxWidth(),
        text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
        onTextLayout = {
            appLog("onTextLayout => size: ${it.size}")
        }
    )
}

textStyle

@Composable
fun TextStyleSample() {
    Text(
        text = "Demo Text",
        style = TextStyle(
            color = Color.Red,
            fontSize = 16.sp,
            fontFamily = FontFamily.Monospace,
            fontWeight = FontWeight.W800,
            fontStyle = FontStyle.Italic,
            letterSpacing = 0.5.em,
            background = Color.LightGray,
            textDecoration = TextDecoration.Underline
        )
    )
}

textStyle

annotatedString

Text(text = with(AnnotatedString.Builder("Hello")) {
    // push green text style so that any appended text will be green
    pushStyle(SpanStyle(color = Color.Green))
    // append new text, this text will be rendered as green
    append(" World")
    // pop the green style
    pop()
    // append a string without style
    append("!")
    // then style the last added word as red, exclamation mark will be red
    addStyle(SpanStyle(color = Color.Red), "Hello World".length, this.length)

    toAnnotatedString()
})

annotatedString

inlineTextContent

@Composable
fun InlineTextContentSample() {
    val myId = "inlineContent"
    val text = buildAnnotatedString {
        append("Hello")
        // Append a placeholder string "[myBox]" and attach an annotation "inlineContent" on it.
        appendInlineContent(myId, "[myBox]")
    }

    val inlineContent = mapOf(
        Pair(
            // This tells the [BasicText] to replace the placeholder string "[myBox]" by
            // the composable given in the [InlineTextContent] object.
            myId,
            InlineTextContent(
                // Placeholder tells text layout the expected size and vertical alignment of
                // children composable.
                Placeholder(
                    width = 0.5.em,
                    height = 0.5.em,
                    placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline
                )
            ) {
                // This [Box] will fill maximum size, which is specified by the [Placeholder]
                // above. Notice the width and height in [Placeholder] are specified in TextUnit,
                // and are converted into pixel by text layout.
                Box(modifier = Modifier.fillMaxSize().background(color = Color.Red))
            }
        )
    )

    Text(text = text, inlineContent = inlineContent)
}

inlineTextContent

onTextLayout

Text(
    modifier = Modifier.fillMaxWidth(),
    text = "上帝, 请赐予我平静, 去接受我无法改变的. 给予我勇气, 去改变我能改变的, 赐我智慧, 分辨这两者的区别.",
    onTextLayout = {
        appLog("onTextLayout => size: ${it.size}")
    }
)

onTextLayout

可选择文本

SelectionContainer(modifier = Modifier.fillMaxWidth()) {
    Text(text = "You can select me, baby")
}

SelectionContainer&Text

可点击文本

方式一:Modifier.clickable

Text(text = "使用 clickable 实现点击",
    modifier = Modifier.clickable {
        appLog("使用 Text clickable 属性完成点击")
    })

方式二:ClickableText

ClickableText(
    text = AnnotatedString(
        text = "Hello World",
        // make "Hello" italic.
        spanStyles = listOf(
            AnnotatedString.Range(SpanStyle(fontStyle = FontStyle.Italic), 0, 5)
        ),
        // create two paragraphs with different alignment and indent settings.
        paragraphStyles = listOf(
            AnnotatedString.Range(ParagraphStyle(textAlign = TextAlign.Center), 0, 6),
            AnnotatedString.Range(ParagraphStyle(textIndent = TextIndent(5.sp)), 6, 11)
        )
    ), onClick = {
        appLog("ClickableText 完成点击, 位置 $it")
    }
)

文本点击事件

源码

https://github.com/onlyloveyd/LearningCompose

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndroidKt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值