📐 布局系统 · 实战

Compose + ViewModel
Column / Row / Box Modifier 链式调用 ConstraintLayout 🎯 第4章
布局核心行为典型 Modifier 链
📌 Column 垂直排列子元素。可设置 verticalArrangement, horizontalAlignment Modifier.fillMaxWidth().padding(12.dp).background(Color.Cyan)
📌 Row 水平排列子元素。可设置 horizontalArrangement, verticalAlignment Modifier.height(IntrinsicSize.Min).weight(1f).border(2.dp, Color.Gray)
📌 Box 层叠布局 (类似FrameLayout)。子元素按顺序堆叠 Modifier.size(120.dp).align(Alignment.Center).clip(CircleShape)
// ===== Column 垂直 =====
@Composable
fun VerticalCard() {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("标题", style = MaterialTheme.typography.h5)
        Divider(thickness = 2.dp, color = Color(0xFFF3CD9B))
        Text("内容区块 · 第4课")
    }
}

// ===== Row 水平 =====
@Composable
fun RowChipGroup() {
    Row(
        modifier = Modifier.horizontalScroll(rememberScrollState()),
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        repeat(5) { index ->
            Chip(text = "标签 #${index + 1}", 
                 modifier = Modifier.weight(1f, fill = false))
        }
    }
}

// ===== Box 层叠 =====
@Composable
fun BoxBadge() {
    Box(modifier = Modifier.size(100.dp).background(Color(0xFFF9D9B1), RoundedCornerShape(20.dp))) {
        Text("底层", modifier = Modifier.align(Alignment.TopStart))
        Icon(Icons.Default.Favorite, contentDescription = null,
             modifier = Modifier.align(Alignment.Center))
        Text("顶层", modifier = Modifier.align(Alignment.BottomEnd))
    }
}
.padding() .fillMaxWidth() .background() .clickable() ⬅ 从左到右依次应用 · 顺序决定效果
ConstraintLayout 约束布局 · 扁平化层级 头像 @+id/avatar 标题文本 @+id/title 描述 @+id/description 🔗 约束链: 头像.start 链接 标题.start , 标题.end 链接 描述.start

⚡ Modifier 链式调用

  • 顺序敏感:先 padding 后 background 效果不同
  • 使用 .then() 合并自定义 Modifier
  • 常用链:.fillMaxWidth().padding(16.dp).clip(RoundedCornerShape(12.dp))
  • 性能优化:尽量合并同类修饰符

🧩 ConstraintLayout 优势

  • 扁平化层级,避免嵌套 Column/Row
  • 相对定位:linkTo 父布局或兄弟
  • 屏障 (Barrier) / 引导线 (Guideline)
  • 适合复杂自适应界面
// ===== ConstraintLayout 示例 =====
@Composable
fun ConstraintCard() {
    ConstraintLayout(
        modifier = Modifier.fillMaxWidth().padding(16.dp)
    ) {
        val (avatar, title, desc) = createRefs()

        Image(
            painter = painterResource(R.drawable.avatar),
            contentDescription = null,
            modifier = Modifier
                .size(48.dp)
                .constrainAs(avatar) {
                    top.linkTo(parent.top)
                    start.linkTo(parent.start)
                }
        )
        Text("标题", modifier = Modifier.constrainAs(title) {
            top.linkTo(avatar.top)
            start.linkTo(avatar.end, margin = 12.dp)
            end.linkTo(parent.end)
        })
        Text("描述内容……", modifier = Modifier.constrainAs(desc) {
            top.linkTo(title.bottom, margin = 4.dp)
            start.linkTo(title.start)
            end.linkTo(parent.end)
        })
    }
}