Compose 基础组件:从 Text 到 Modifier
各位同学,今天我们来聊聊 Compose 里最基础、也最常用的一些组件。说实话,这些组件你天天都会用到,但很多人用着用着就踩坑了。我刚开始从 XML 切到 Compose 时,也犯过不少低级错误。嗯,咱们今天就把它彻底讲透。
核心知识点一览:
- Text:不只是显示文字那么简单
- Button:点击交互的基石
- Image:图片加载与适配
- TextField:输入框的正确打开方式
- Column、Row、Box:三大布局容器
- Modifier:万物皆可修饰
Text:不只是显示文字
Text 是 Compose 里最常用的组件,没有之一。你想想看,哪个 App 没有文字?但很多人只用了最基本的 Text("Hello"),其实它的能力远不止这些。
@Composable
fun TextDemo() {
Text(
text = "Hello Compose",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color.Blue,
textAlign = TextAlign.Center,
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
我的经验: 在项目中处理长文本时,一定要设置 maxLines 和 overflow。我曾经有个列表页,用户昵称特别长,直接撑爆了布局。加上 TextOverflow.Ellipsis 后,世界清净了。
Text 还支持 style 参数,可以复用 Material Design 的文本样式:
Text(
text = "标题样式",
style = MaterialTheme.typography.h5
)
Button:点击交互的基石
Button 在 Compose 里比 XML 时代简洁太多了。以前要写一堆 selector、shape,现在几行搞定。
@Composable
fun ButtonDemo() {
Button(
onClick = { /* 处理点击 */ },
enabled = true,
colors = ButtonDefaults.buttonColors(
containerColor = Color.Blue,
contentColor = Color.White
)
) {
Text("点击我")
}
}
注意: Button 的 onClick 不能为 null。如果你需要条件禁用,用 enabled 参数控制,而不是传 null。这是 Compose 的设计哲学——避免空指针。
我个人习惯把按钮的点击事件抽成 lambda,这样预览和测试都方便。另外,OutlinedButton 和 TextButton 也是常用变体,适合不同场景。
Image:图片加载与适配
Image 组件本身不负责网络加载,它只负责显示。实际项目中我们通常配合 Coil 或 Glide 的 Compose 扩展使用。
@Composable
fun ImageDemo() {
// 加载本地资源
Image(
painter = painterResource(id = R.drawable.ic_launcher),
contentDescription = "应用图标",
modifier = Modifier.size(100.dp),
contentScale = ContentScale.Crop
)
}
contentScale 这个参数很关键。它决定了图片如何适配容器。我见过不少新手用 Fit 导致图片变形,其实 Crop 或 FillBounds 更常用。
避坑指南: 我曾经在列表中使用大图时没加 contentScale,结果图片拉伸得不成样子。后来统一用 ContentScale.Crop 配合固定宽高,问题解决。
TextField:输入框的正确打开方式
TextField 在 Compose 里分两种:TextField(经典风格)和 OutlinedTextField(外框风格)。我个人更推荐后者,视觉上更清晰。
@Composable
fun TextFieldDemo() {
var text by remember { mutableStateOf("") }
OutlinedTextField(
value = text,
onValueChange = { text = it },
label = { Text("用户名") },
placeholder = { Text("请输入用户名") },
singleLine = true,
modifier = Modifier.fillMaxWidth()
)
}
这里有个关键点:remember 和 mutableStateOf 是 Compose 状态管理的核心。没有它们,输入框不会响应你的输入。说白了,Compose 是「状态驱动 UI」的,状态变了 UI 自动更新。
我的建议: 对于密码输入框,记得加 visualTransformation = PasswordVisualTransformation()。另外,keyboardOptions 可以控制键盘类型,比如数字键盘用 KeyboardType.Number。
Column、Row、Box:三大布局容器
这三个容器是 Compose 布局的基石。Column 垂直排列,Row 水平排列,Box 层叠排列。理解它们,你就掌握了 90% 的布局场景。
@Composable
fun LayoutDemo() {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("上面")
Spacer(modifier = Modifier.height(16.dp))
Text("下面")
}
}
Arrangement 控制主轴方向的对齐,Alignment 控制交叉轴。嗯,这两个概念容易混淆,记住:Column 的主轴是垂直方向,Row 的主轴是水平方向。
Box 的特殊用法: Box 常用于叠加效果,比如在图片上覆盖文字。它的 contentAlignment 参数可以控制所有子元素的对齐方式。
Box(
modifier = Modifier.size(200.dp),
contentAlignment = Alignment.BottomCenter
) {
Image(...)
Text("底部文字", color = Color.White)
}
Modifier:万物皆可修饰
Modifier 是 Compose 最强大的设计之一。它采用链式调用,可以给任何组件添加 padding、背景、点击事件、大小等属性。说白了,它就是 Compose 的「瑞士军刀」。
@Composable
fun ModifierDemo() {
Text(
text = "带修饰的文字",
modifier = Modifier
.padding(16.dp)
.background(Color.LightGray)
.clickable { /* 点击 */ }
.fillMaxWidth()
)
}
Modifier 的顺序很重要!padding 和 background 的顺序不同,效果完全不同。我刚开始学的时候经常搞混,后来记住一个原则:先大小后间距,先背景后点击。
曾经踩过的坑: 我在一个项目中把 clickable 放在了 padding 前面,结果点击区域包含了 padding 部分,导致用户点击空白区域也有响应。正确的做法是把 clickable 放在最后。
Modifier 还支持自定义扩展。比如你可以写一个 Modifier.shadow() 的扩展函数,给组件添加阴影效果。这就是 Compose 的灵活之处。
总结
今天讲的这些组件,每个都很简单,但组合起来就能构建出复杂的 UI。记住几个要点:
- Text 记得处理溢出
- Button 用 enabled 控制状态
- Image 注意 contentScale
- TextField 必须配合 remember
- Column/Row/Box 分清主轴和交叉轴
- Modifier 顺序决定最终效果
这些基础打牢了,后面学高级组件会轻松很多。嗯,今天就到这里,大家动手写写看。