1. Compose开发中的文本与样式基础
Jetpack Compose作为Android现代UI工具包,彻底改变了我们构建用户界面的方式。在Compose中处理文本和样式与传统的View系统有着本质区别。我刚开始接触Compose时,最不适应的就是这种声明式的文本和样式管理方式,但一旦掌握就会发现它的强大之处。
Compose中的文本通过Text组件呈现,而样式则通过Modifier和TextStyle来定义。这种分离设计让代码更清晰,也更容易复用。比如一个简单的带样式文本可以这样写:
kotlin复制Text(
text = "Hello Compose",
style = TextStyle(
color = Color.Blue,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
)
这种声明式写法比XML布局直观多了,而且样式可以直接复用。在实际项目中,我通常会先定义好一套文本样式常量:
kotlin复制object AppTextStyles {
val titleLarge = TextStyle(
fontSize = 22.sp,
fontWeight = FontWeight.Bold,
lineHeight = 28.sp
)
// 其他预定义样式...
}
提示:使用
sp单位而不是dp来定义字体大小,这样会尊重用户的系统字体大小设置
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 高级文本样式技巧
2.1 多段落与富文本
Compose支持通过AnnotatedString实现富文本效果,这比传统的SpannableString更强大也更易用。比如要实现一段文字中部分高亮:
kotlin复制Text(
buildAnnotatedString {
append("这是普通文本")
withStyle(style = SpanStyle(color = Color.Red)) {
append("这是红色文本")
}
append("又回到普通文本")
}
)
我在一个电商App中就用这个特性实现了商品搜索关键词高亮。相比旧方案,代码量减少了60%,性能还提升了。
2.2 自定义字体与图标字体
加载自定义字体很简单:
kotlin复制val customFont = FontFamily(
Font(R.font.my_font, FontWeight.Normal)
)
Text(
text = "自定义字体",
style = TextStyle(fontFamily = customFont)
)
对于图标字体,我推荐使用androidx.compose.material:material-icons-extended库,它包含了丰富的Material图标:
kotlin复制Text(
stringResource(id = R.string.icon_account),
fontFamily = Icons.Default.fontFamily
)
注意:字体文件会增加APK体积,建议使用字体子集或延迟加载
3. 样式管理与主题系统
3.1 创建自定义主题
Compose的主题系统基于Material Design,但完全可定制。定义主题的推荐方式:
kotlin复制object MyTheme {
val colors = lightColors(
primary = Color(0xFF6200EE),
secondary = Color(0xFF03DAC6)
)
val typography = Typography(
h1 = TextStyle(...),
body1 = TextStyle(...)
// 其他文本样式...
)
}
应用主题只需用MaterialTheme包装:
kotlin复制MaterialTheme(
colors = MyTheme.colors,
typography = MyTheme.typography
) {
// 你的UI组件
}
3.2 暗黑模式适配
实现暗黑模式切换出奇简单:
kotlin复制val isDarkTheme = remember { mutableStateOf(false) }
MaterialTheme(
colors = if (isDarkTheme.value) darkColors() else lightColors()
) {
// 主题感知的UI
}
在我的一个项目中,通过结合系统设置和用户偏好,实现了无缝的主题切换体验:
kotlin复制val context = LocalContext.current
val systemDarkMode = remember {
context.resources.configuration.uiMode and
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
}
4. 响应式文本与布局
4.1 屏幕尺寸适配
Compose提供了几种处理不同屏幕尺寸的方式:
- 基于宽度的断点:
kotlin复制val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.dp
val textStyle = when {
screenWidth < 600.dp -> TextStyle(fontSize = 14.sp)
screenWidth < 840.dp -> TextStyle(fontSize = 16.sp)
else -> TextStyle(fontSize = 18.sp)
}
- 使用
BoxWithConstraints:
kotlin复制BoxWithConstraints {
val responsiveFontSize = if (maxWidth < 400.dp) 12.sp else 16.sp
Text("响应式文本", fontSize = responsiveFontSize)
}
4.2 多语言文本处理
处理多语言文本时要注意:
- 使用
stringResource而不是硬编码字符串 - 考虑RTL(从右到左)语言布局:
kotlin复制Text(
text = stringResource(R.string.welcome),
style = MaterialTheme.typography.body1,
textAlign = if (LocalLayoutDirection.current == LayoutDirection.Rtl)
TextAlign.End else TextAlign.Start
)
5. 性能优化与常见问题
5.1 文本测量性能
Compose的文本测量有时会成为性能瓶颈。优化技巧:
- 避免在
Column/Row中频繁测量:
kotlin复制// 不推荐 - 会多次测量
Column {
Text("标题")
Text("副标题")
}
// 推荐 - 单次测量
Text("标题\n副标题")
- 对长文本使用
remember缓存计算结果
5.2 常见问题排查
- 文本截断问题:
kotlin复制Text(
text = "很长很长的文本...",
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
- 样式不生效:
- 检查是否被父组件样式覆盖
- 确认
Modifier顺序正确(后定义的会覆盖前面的)
- 字体不显示:
- 检查字体文件是否正确放置在
res/font/目录 - 确认字体文件有正确的文件扩展名(如.ttf)
6. 实战:构建一个富文本编辑器
结合前面所学,我们来实现一个简单的富文本编辑器:
kotlin复制@Composable
fun RichTextEditor() {
var text by remember { mutableStateOf(AnnotatedString("")) }
var isBold by remember { mutableStateOf(false) }
Column {
// 工具栏
Row {
IconButton(onClick = { isBold = !isBold }) {
Icon(Icons.Default.FormatBold, "加粗")
}
// 其他格式按钮...
}
// 编辑区域
BasicTextField(
value = text,
onValueChange = { newText ->
text = if (isBold) {
buildAnnotatedString {
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
append(newText.text)
}
}
} else {
newText
}
},
textStyle = TextStyle(fontSize = 16.sp)
)
}
}
这个编辑器虽然简单,但包含了Compose文本处理的核心概念。在实际项目中,你可以进一步扩展:
- 添加更多文本样式选项
- 实现撤销/重做功能
- 支持图片插入
我在开发这类组件时最大的心得是:充分利用Compose的状态管理能力,把文本状态和UI表现分离,这样代码会更清晰可维护。
