Skip to content

基础布局 (Layouts)

源:Compose 布局基础知识

在 Compose 中,通过组合不同的布局函数,可以构建出极其复杂的 UI 结构。

1. 三大基础布局

kotlin
Column(
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.spacedBy(8.dp)
) {
    Text("第一行")
    Text("第二行")
}
kotlin
Row(
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.SpaceBetween
) {
    Icon(Icons.Default.Star, contentDescription = null)
    Text("评分: 5.0")
}
kotlin
Box {
    Image(painterResource(id = R.drawable.bg), null)
    Text(
        "置顶文字", 
        modifier = Modifier.align(Alignment.Center)
    )
}

Box 特有修饰符:matchParentSize()

与 fillMaxSize() 的区别

  • fillMaxSize(): 请求父容器的所有可用空间。这可能会影响父容器的最终尺寸。
  • matchParentSize(): 不影响父容器尺寸,仅在父容器测量完其他子项并确定尺寸后,将自己设置为与父容器一样大。
kotlin
Box {
    // 这个 Spacer 会填满 Box,但 Box 的大小完全由 Text 决定
    Spacer(Modifier.matchParentSize().background(Color.Gray))
    Text("我是决定大小的内容")
}

2. 权重 (Weight)

权重允许子项填充父容器中的剩余空间。

比例分配

如果两个子项权重分别为 1f2f,则它们会按 1:2 的比例分配空间。

kotlin
Row {
    Box(Modifier.weight(1f).height(50.dp).background(Color.Red))
    Box(Modifier.weight(1f).height(50.dp).background(Color.Blue))
}

3. 流式布局 (Flow Layouts)

流式布局允许子项在空间不足时自动换行,常用于显示标签(Tags)或不规则网格。

kotlin
FlowRow(
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    verticalArrangement = Arrangement.spacedBy(8.dp)
) {
    tags.forEach { tag ->
        AssistChip(onClick = {}, label = { Text(tag) })
    }
}
kotlin
FlowColumn {
    // 元素从上到下排列,满了后换到右侧一列
    items.forEach { item ->
        Text(item)
    }
}

4. Scaffold (标准脚手架)

Scaffold 提供了一个符合 Material Design 的顶层容器,包含标题栏、底部栏、悬浮按钮等插槽。

必须应用内边距

innerPadding 包含来自 TopBar、BottomBar 的高度信息,必须应用到内容布局中,否则内容会被遮挡。

kotlin
Scaffold(
    topBar = { TopAppBar(title = { Text("标题") }) },
    bottomBar = { BottomAppBar { /* ... */ } }
) { innerPadding ->
    Column(modifier = Modifier.padding(innerPadding)) {
        // 主要内容
    }
}