Compose中Text的使用:

0 阅读3分钟

一、基础使用

1、使用:

最简化的 Text 只需传入要显示的字符串即可,Compose 会使用默认样式(系统字体、默认字号、黑色文字)。

@Composable
fun BasicTextDemo() {
  Text(
    //text = "自定义样式文本",
    text = stringResource(R.string.app_name),
    // 文字颜色
    // color = Color.Blue,
    color = colorResource(R.color.purple_200),
    // 字体大小(单位:sp,Compose 中 dp/sp 需显式指定)
    //fontSize = 20.sp,
     fontSize =  Dimens.fontXLarge,
     // 字体粗细(可选:Light(300)、Normal(400)、Bold(700)、Black(900) 等)
    fontWeight = FontWeight.Bold,
    // 斜体
    fontStyle = FontStyle.Italic,
    // 行高(文字行间距,需大于 fontSize)
    lineHeight = 30.sp,
    // 字符间距
    letterSpacing = 2.sp
  )
  
//需要dp的可以使用这种方式
Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.ui_dp_16)))
}

Kotlin中的字体大小:

object Dimens {
    val fontSmall = 12.sp
    val fontNormal = 16.sp
    val fontLarge = 20.sp
    val fontXLarge = 24.sp
}

注意:

  • 1、引用本地String的值:text = stringResource(R.string.app_name),
  • 2、引用本地字体颜色: color = colorResource(R.color.purple_200),
  • 3、引用本地字体大小: fontSize 需要的是TextUnit ,不能使用这种方式dimensionResource;可以使用Kotlin中的fontSize = Dimens.fontXLarge;
  • 4、这个就可以:Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.ui_dp_16))),
  • 5、Modifier.padding也可以;
Column(modifier = Modifier.padding(start = dimensionResource(id = R.dimen.ui_dp_16)))

2、dimes可以配置到代码中,也可以配置到XML中:

配置到代码中:
// 统一管理的字体大小常量(放在单独的文件,如 Dimens.kt)
object Dimens {
    val fontSmall = 12.sp
    val fontNormal = 16.sp
    val fontLarge = 20.sp
    val fontXLarge = 24.sp
}

@Composable
fun CustomFontSizeDemo() {
    // 引用本地常量的字体大小
    Text(
        text = "正常字体(16sp)",
        fontSize = Dimens.fontNormal
    )

    Text(
        text = "大号字体(20sp)",
        fontSize = Dimens.fontLarge
    )
}
配置到XML中:

c6f8dba35f84656869f871a506f886f7.png

分类参数名作用常用值 / 示例
核心内容text显示的文本(String/AnnotatedString)"文本内容" / buildAnnotatedString { ... }
文本样式fontFamily字体家族(系统 / 自定义)FontFamily.Sans / FontFamily(Font(R.font.my_font))
文本样式letterSpacing字符间距(正负值均可)1.sp(增大)/ -0.5.sp(缩小)
文本样式baselineShift基线偏移(调整文字上下位置,用于下标 / 上标)BaselineShift.Subscript(下标)/ BaselineShift.Superscript(上标)/ 0.2f
文本样式textGeometricTransform文字几何变换(缩放 / 倾斜)TextGeometricTransform(scaleX = 1.2f, skewX = 0.1f)
文本样式locale文本本地化(影响换行、排序、标点规则)Locale.ENGLISH / Locale.CHINA
排版控制maxLines最大显示行数(超出后按 overflow 处理)2 / Int.MAX_VALUE(不限制)
排版控制minLines最小显示行数(即使文本为空 / 不足,也占对应行数空间)1 / 3
排版控制softWrap是否允许换行(false 则强制单行)true(默认)/ false
排版控制overflow溢出处理规则TextOverflow.Ellipsis(省略号)/ TextOverflow.Clip(截断)/ TextOverflow.Visible(强制显示)
布局相关modifier布局修饰符(尺寸、边距、点击、背景等)Modifier.width(200.dp).padding(8.dp).clickable { ... }
辅助配置onTextLayout文本布局完成后的回调(获取行数、字符位置、宽高等信息)onTextLayout = { layoutResult -> Log.d("Text", "行数:${layoutResult.lineCount}") }
辅助配置selectionColors文本选中时的颜色(仅支持可选中的 Text,需配合 SelectionContainerSelectionColors(handleColor = Color.Red, backgroundColor = Color.LightGray)

二、核心样式配置

Text 的样式主要通过 modifier(布局相关)和 style/ 直接参数(文本样式)配置,以下是高频使用的参数:

1. 文本样式(字体、大小、颜色、粗细等)

可通过两种方式配置:

  • 方式 1:直接通过 Text 的参数设置(推荐简单样式);
  • 方式 2:通过 TextStyle 封装样式(推荐复用 / 复杂样式)。
@Composable
fun StyledTextDemo() {
    Column(modifier = Modifier.padding(16.dp)) {
        // 方式1:直接传参
        Text(
            text = "自定义样式文本",
            // 文字颜色
            color = Color.Blue,
            // 字体大小(单位:sp,Compose 中 dp/sp 需显式指定)
            fontSize = 20.sp,
            // 字体粗细(可选:Light(300)、Normal(400)、Bold(700)、Black(900) 等)
            fontWeight = FontWeight.Bold,
            // 斜体
            fontStyle = FontStyle.Italic,
            // 行高(文字行间距,需大于 fontSize)
            lineHeight = 30.sp,
            // 字符间距
            letterSpacing = 2.sp
        )

        Spacer(modifier = Modifier.height(16.dp))

        // 方式2:通过 TextStyle 封装(复用性更强)
        val customTextStyle = TextStyle(
            color = Color.Red,
            fontSize = 18.sp,
            fontWeight = FontWeight.Medium,
            fontFamily = FontFamily.Monospace, // 等宽字体
            textDecoration = TextDecoration.Underline // 下划线(可选:LineThrough 删除线)
        )
        Text(
            text = "通过TextStyle配置样式",
            style = customTextStyle
        )
    }
}

2. 文本对齐与换行

控制文本的排版、换行、溢出处理:

@Composable
fun TextAlignmentDemo() {
    Text(
        text = "这是一段超长的文本,用于测试换行和溢出处理效果,看看超出宽度后会如何显示",
        modifier = Modifier
            .width(200.dp) // 限制文本宽度
            .background(Color.LightGray),
        // 文本对齐方式(Left/Right/Center/Start/End)
        textAlign = TextAlign.Center,
        // 换行规则(Wrap/NoWrap)
        softWrap = true,
        // 溢出处理(Ellipsis 省略号/Clip 截断/Visible 强制显示)
        overflow = TextOverflow.Ellipsis,
        // 最大显示行数
        maxLines = 2
    )
}

三、高级用法

1. 富文本(不同样式的文本拼接)

通过 AnnotatedString 实现一段文本内不同样式(如部分文字变色、加粗):

@Composable
fun RichTextDemo() {
    // 1. 构建带样式的 AnnotatedString
    val richText = buildAnnotatedString {
        // 普通文本
        append("这是一段")

        // 带样式的文本
        withStyle(
            style = SpanStyle(
                color = Color.Green,
                fontWeight = FontWeight.Bold,
                fontSize = 18.sp
            )
        ) {
            append("富文本")
        }

        // 继续追加普通文本
        append("示例,支持部分文字样式自定义")
    }

    // 2. 显示富文本
    Text(
        text = richText,
        modifier = Modifier.padding(16.dp)
    )
}

2. 点击事件(整体 / 部分文本点击)

  • 整体文本点击:通过 modifier.clickable
  • 部分文本点击:通过 AnnotatedString 标记可点击区域 + ClickableText 组件。
@Composable
fun ClickableTextDemo() {
    Column(modifier = Modifier.padding(16.dp)) {
        // 1. 整体文本可点击
        Text(
            text = "点击我触发事件",
            modifier = Modifier
                .clickable {
                   // Toast.makeText(LocalContext.current, "文本被点击", Toast.LENGTH_SHORT).show()
                   Log.d("lyy","--文本被点击--")
                }
                .background(Color.LightGray)
                .padding(8.dp),
            color = Color.Blue
        )

        Spacer(modifier = Modifier.height(16.dp))

        // 2. 部分文本可点击(如“隐私政策”)
        val clickableText = buildAnnotatedString {
            append("注册即表示同意我们的")
            // 标记可点击区域(添加标签)
            pushStringAnnotation(
                tag = "policy",
                annotation = "隐私政策"
            )
            withStyle(SpanStyle(color = Color.Blue)) {
                append("隐私政策")
            }
            pop() // 结束标记
        }

        ClickableText(
            text = clickableText,
            onClick = { offset ->
                // 根据点击位置获取标记的内容
                clickableText.getStringAnnotations(tag = "policy", start = offset, end = offset)
                    .firstOrNull()?.let {
                      //  Toast.makeText(LocalContext.current, "点击了${it.item}", Toast.LENGTH_SHORT).show()
                        Log.d("lyy","点击了${it.item}")

                    }
            }
        )
    }
}

3. 自定义字体

加载本地自定义字体(需将字体文件放在 res/font/ 目录下):

@Composable
fun CustomFontTextDemo() {
    // 加载自定义字体(示例:font/custom_font.ttf)
    val customFont = FontFamily(
        Font(R.font.custom_font, FontWeight.Normal)
    )

    Text(
        text = "使用自定义字体的文本",
        fontFamily = customFont,
        fontSize = 22.sp,
        modifier = Modifier.padding(16.dp)
    )
}

四、注意事项

  1. sp vs dp:字体大小必须用 sp(适配系统字体缩放),布局尺寸用 dp
  2. 性能优化:频繁变化的文本(如倒计时)建议用 remember 缓存 String,避免重复重组;
  3. 国际化:不要硬编码字符串,建议通过 stringResource 读取 res/values/strings.xml 中的文本:
Text(text = stringResource(id = R.string.hello_compose))
Text(text = "你好",
    color = colorResource(R.color.purple_500)
    )

五、高级用法:

1. 下标 / 上标(如数学公式、单位)

@Composable
fun SubSuperscriptDemo() {
    Text(
        text = buildAnnotatedString {
            // 正常文字
            append("H")
            // 下标(水的化学式 H₂O)
            withStyle(SpanStyle(baselineShift = BaselineShift.Subscript, fontSize = 12.sp)) {
                append("2")
            }
            append("O  ")

            // 上标(平方)
            append("X")
            withStyle(SpanStyle(baselineShift = BaselineShift.Superscript, fontSize = 12.sp)) {
                append("2")
            }
            pop() // 结束标记
        },
        fontSize = 18.sp,
        modifier = Modifier.padding(16.dp)
    )
}

2、空文本 / 占位符处理

@Composable
fun EmptyTextDemo(text: String?) {
    Text(
        text = text ?: "暂无数据", // 空值默认显示占位符
        color = if (text.isNullOrEmpty()) Color.Red else Color.Black, // 占位符灰色
        modifier = Modifier.padding(16.dp)
    )
}

3、动态文本(如网络请求后更新)

@Composable
fun DynamicTextDemo() {
    // 可观察的状态变量(mutableStateOf)
    var dynamicText by remember { mutableStateOf("初始文本") }

    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = dynamicText)

        Spacer(modifier = Modifier.height(16.dp))

        Button(onClick = {
            // 点击按钮更新文本,界面自动重组
            dynamicText = "更新后的文本:${System.currentTimeMillis()}"
        }) {
            Text("更新文本")
        }
    }
}

4、文本自适应宽度(单行居中 / 两端对齐)

@Composable
fun JustifyTextDemo() {
    Text(
        text = "这是一段需要两端对齐的文本,通常用于正文排版,让每行文字左右都对齐",
        modifier = Modifier
            .fillMaxWidth() // 占满父布局宽度
            .padding(16.dp),
        textAlign = TextAlign.Center, // 两端对齐(仅多行生效)
        lineHeight = 24.sp
    )
}

六、性能优化技巧

  • 缓存静态文本:如果文本内容固定,用 remember 缓存,避免每次重组重新创建:
val staticText = remember { "固定不变的文本" }
Text(text = staticText)
  • 避免频繁创建 TextStyle:复用 TextStyle 实例,而非每次重组都新建:

@Composable
fun ReusableStyleDemo() {
    // 用 remember 缓存 TextStyle
    val reusableStyle = remember {
        TextStyle(
            fontSize = 16.sp,
            color = Color.Black,
            fontWeight = FontWeight.Medium
        )
    }
    Text(text = "复用样式", style = reusableStyle)
}
  • 减少 onTextLayout 回调的耗时操作:该回调会在布局变化时频繁触发,避免在里面做网络请求、复杂计算等。

  • 避免嵌套 SelectionContainerSelectionContainer 会增加布局开销,仅在需要选中的文本外层使用。