Jetpack Compose 中 Row 与 Column 布局

4 阅读12分钟

Jetpack Compose 中 Row 与 Column 布局

目录

  1. 概述
  2. Row 布局详解
  3. Column 布局详解
  4. 参数配置与组合使用
  5. RowScope 与 ColumnScope
  6. 常见问题与最佳实践
  7. 完整代码示例

一、概述

Jetpack Compose 提供了两种最基础的线性布局容器:RowColumn

布局容器排列方向主轴交叉轴
Row水平方向水平 (Horizontal)垂直 (Vertical)
Column垂直方向垂直 (Vertical)水平 (Horizontal)
Row 布局示意图:
┌─────────────────────────────────────┐
│  [Item1]  [Item2]  [Item3]  [Item4] │  ← 水平排列
└─────────────────────────────────────┘

Column 布局示意图:
┌─────────┐
│ [Item1] │
├─────────┤
│ [Item2] │
├─────────┤
│ [Item3] │  ← 垂直排列
├─────────┤
│ [Item4] │
└─────────┘

二、Row 布局详解

2.1 基本定义

Row 是一个水平方向的线性布局容器,用于在水平轴上排列其子组件。

@Composable
inline fun Row(
    modifier: Modifier = Modifier,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    content: @Composable RowScope.() -> Unit
)

参数说明:

参数类型默认值说明
modifierModifierModifier用于修改布局的修饰符
horizontalArrangementArrangement.HorizontalArrangement.Start水平方向排列方式
verticalAlignmentAlignment.VerticalAlignment.Top垂直方向对齐方式
contentRowScope.() -> Unit-子组件内容

2.2 horizontalArrangement 参数详解

horizontalArrangement 用于控制子组件在水平方向上的排列方式。

Arrangement 效果示意图:

Start:          [A][B][C]                
End:                     [A][B][C]       
Center:           [A][B][C]              
SpaceBetween:   [A]      [B]      [C]    
SpaceAround:   [A]    [B]    [C]         
SpaceEvenly:  [A]   [B]   [C]            
参数值意义适用场景
Arrangement.Start子组件从水平方向的起始位置开始排列(默认值)左对齐布局
Arrangement.End子组件从水平方向的结束位置开始排列右对齐布局
Arrangement.Center子组件在水平方向上居中排列居中对齐
Arrangement.SpaceBetween子组件之间均匀分布,首尾子组件分别位于起始和结束位置两端对齐
Arrangement.SpaceAround子组件之间均匀分布,首尾子组件与容器边缘有一半的间距均匀分布带边距
Arrangement.SpaceEvenly子组件之间及与容器边缘的间距均相等完全均匀分布
Arrangement.spacedBy(dp, alignment)自定义子组件之间的固定间距固定间距布局

代码示例:

@Composable
fun RowArrangementDemo() {
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // Start
        ArrangementRow(
            title = "Arrangement.Start",
            arrangement = Arrangement.Start
        )
        
        // Center
        ArrangementRow(
            title = "Arrangement.Center",
            arrangement = Arrangement.Center
        )
        
        // End
        ArrangementRow(
            title = "Arrangement.End",
            arrangement = Arrangement.End
        )
        
        // SpaceBetween
        ArrangementRow(
            title = "Arrangement.SpaceBetween",
            arrangement = Arrangement.SpaceBetween
        )
        
        // SpaceAround
        ArrangementRow(
            title = "Arrangement.SpaceAround",
            arrangement = Arrangement.SpaceAround
        )
        
        // SpaceEvenly
        ArrangementRow(
            title = "Arrangement.SpaceEvenly",
            arrangement = Arrangement.SpaceEvenly
        )
        
        // spacedBy
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.LightGray)
                .padding(8.dp),
            horizontalArrangement = Arrangement.spacedBy(24.dp)
        ) {
            DemoBox(text = "A")
            DemoBox(text = "B")
            DemoBox(text = "C")
        }
        Text("Arrangement.spacedBy(24.dp)", fontSize = 12.sp, color = Color.Gray)
    }
}

@Composable
private fun ArrangementRow(
    title: String,
    arrangement: Arrangement.Horizontal
) {
    Column {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.LightGray)
                .padding(8.dp),
            horizontalArrangement = arrangement
        ) {
            DemoBox(text = "A")
            DemoBox(text = "B")
            DemoBox(text = "C")
        }
        Text(title, fontSize = 12.sp, color = Color.Gray)
    }
}

@Composable
private fun DemoBox(text: String) {
    Box(
        modifier = Modifier
            .size(40.dp)
            .background(Color(0xFF6200EE)),
        contentAlignment = Alignment.Center
    ) {
        Text(text, color = Color.White, fontWeight = FontWeight.Bold)
    }
}

2.3 verticalAlignment 参数详解

verticalAlignment 用于控制子组件在垂直方向上的对齐方式。

VerticalAlignment 效果示意图:

Top:        ┌───┐ ┌───┐ ┌───┐
            │ A │ │ B │ │ C │
            └───┘ └───┘ └───┘

Center:     ┌───┐ ┌───┐ ┌───┐
            │ A │ │ B │ │ C │
            └───┘ └───┘ └───┘
            
Bottom:     ┌───┐ ┌───┐ ┌───┐
            │ A │ │ B │ │ C │
            └───┘ └───┘ └───┘
参数值意义适用场景
Alignment.Top子组件与垂直方向的顶部对齐(默认值)顶部对齐
Alignment.CenterVertically子组件在垂直方向上居中对齐垂直居中
Alignment.Bottom子组件与垂直方向的底部对齐底部对齐

代码示例:

@Composable
fun RowAlignmentDemo() {
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // Top
        AlignmentRow(
            title = "Alignment.Top",
            alignment = Alignment.Top
        )
        
        // CenterVertically
        AlignmentRow(
            title = "Alignment.CenterVertically",
            alignment = Alignment.CenterVertically
        )
        
        // Bottom
        AlignmentRow(
            title = "Alignment.Bottom",
            alignment = Alignment.Bottom
        )
    }
}

@Composable
private fun AlignmentRow(
    title: String,
    alignment: Alignment.Vertical
) {
    Column {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .height(80.dp)
                .background(Color.LightGray)
                .padding(8.dp),
            verticalAlignment = alignment,
            horizontalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            Box(
                modifier = Modifier
                    .size(30.dp)
                    .background(Color.Red)
            )
            Box(
                modifier = Modifier
                    .size(50.dp)
                    .background(Color.Green)
            )
            Box(
                modifier = Modifier
                    .size(40.dp)
                    .background(Color.Blue)
            )
        }
        Text(title, fontSize = 12.sp, color = Color.Gray)
    }
}

2.4 Row 综合使用示例

@Composable
fun RowCompleteExample() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(24.dp)
    ) {
        // 示例1:工具栏布局
        ToolbarExample()
        
        // 示例2:卡片信息行
        CardInfoRow()
        
        // 示例3:标签组
        TagGroupExample()
    }
}

@Composable
private fun ToolbarExample() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(56.dp)
            .background(Color(0xFF6200EE))
            .padding(horizontal = 16.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        // 左侧:返回按钮
        Icon(
            imageVector = Icons.Default.ArrowBack,
            contentDescription = "Back",
            tint = Color.White
        )
        
        // 中间:标题
        Text(
            text = "页面标题",
            color = Color.White,
            fontSize = 20.sp,
            fontWeight = FontWeight.Medium
        )
        
        // 右侧:菜单按钮
        Icon(
            imageVector = Icons.Default.MoreVert,
            contentDescription = "Menu",
            tint = Color.White
        )
    }
}

@Composable
private fun CardInfoRow() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.White, RoundedCornerShape(8.dp))
            .padding(16.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        // 左侧信息
        Row(
            horizontalArrangement = Arrangement.spacedBy(12.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Box(
                modifier = Modifier
                    .size(48.dp)
                    .background(Color(0xFFE3F2FD), CircleShape),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    imageVector = Icons.Default.Person,
                    contentDescription = null,
                    tint = Color(0xFF1976D2)
                )
            }
            
            Column {
                Text(
                    text = "用户名",
                    fontWeight = FontWeight.Bold,
                    fontSize = 16.sp
                )
                Text(
                    text = "user@example.com",
                    fontSize = 14.sp,
                    color = Color.Gray
                )
            }
        }
        
        // 右侧箭头
        Icon(
            imageVector = Icons.Default.ChevronRight,
            contentDescription = null,
            tint = Color.Gray
        )
    }
}

@Composable
private fun TagGroupExample() {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        val tags = listOf("Android", "Kotlin", "Compose", "Jetpack")
        tags.forEach { tag ->
            Box(
                modifier = Modifier
                    .background(Color(0xFFF5F5F5), RoundedCornerShape(16.dp))
                    .padding(horizontal = 12.dp, vertical = 6.dp)
            ) {
                Text(
                    text = tag,
                    fontSize = 14.sp,
                    color = Color.DarkGray
                )
            }
        }
    }
}

三、Column 布局详解

3.1 基本定义

Column 是一个垂直方向的线性布局容器,用于在垂直轴上排列其子组件。

@Composable
inline fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
)

参数说明:

参数类型默认值说明
modifierModifierModifier用于修改布局的修饰符
verticalArrangementArrangement.VerticalArrangement.Top垂直方向排列方式
horizontalAlignmentAlignment.HorizontalAlignment.Start水平方向对齐方式
contentColumnScope.() -> Unit-子组件内容

3.2 verticalArrangement 参数详解

verticalArrangement 用于控制子组件在垂直方向上的排列方式。

参数值意义适用场景
Arrangement.Top子组件从垂直方向的起始位置开始排列(默认值)顶部对齐布局
Arrangement.Bottom子组件从垂直方向的结束位置开始排列底部对齐布局
Arrangement.Center子组件在垂直方向上居中排列垂直居中布局
Arrangement.SpaceBetween子组件之间均匀分布,首尾子组件分别位于起始和结束位置垂直两端对齐
Arrangement.SpaceAround子组件之间均匀分布,首尾子组件与容器边缘有一半的间距均匀分布带边距
Arrangement.SpaceEvenly子组件之间及与容器边缘的间距均相等完全均匀分布
Arrangement.spacedBy(dp, alignment)自定义子组件之间的固定间距固定间距布局

代码示例:

@Composable
fun ColumnArrangementDemo() {
    Row(
        modifier = Modifier.padding(16.dp),
        horizontalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // Top
        ArrangementColumn(
            title = "Top",
            arrangement = Arrangement.Top
        )
        
        // Center
        ArrangementColumn(
            title = "Center",
            arrangement = Arrangement.Center
        )
        
        // Bottom
        ArrangementColumn(
            title = "Bottom",
            arrangement = Arrangement.Bottom
        )
        
        // SpaceBetween
        ArrangementColumn(
            title = "SpaceBetween",
            arrangement = Arrangement.SpaceBetween
        )
    }
}

@Composable
private fun ArrangementColumn(
    title: String,
    arrangement: Arrangement.Vertical
) {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Column(
            modifier = Modifier
                .width(80.dp)
                .height(200.dp)
                .background(Color.LightGray)
                .padding(8.dp),
            verticalArrangement = arrangement,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            DemoBox(text = "1")
            DemoBox(text = "2")
            DemoBox(text = "3")
        }
        Text(title, fontSize = 10.sp, color = Color.Gray)
    }
}

3.3 horizontalAlignment 参数详解

horizontalAlignment 用于控制子组件在水平方向上的对齐方式。

参数值意义适用场景
Alignment.Start子组件与水平方向的起始位置对齐(默认值)左对齐
Alignment.CenterHorizontally子组件在水平方向上居中对齐水平居中
Alignment.End子组件与水平方向的结束位置对齐右对齐

代码示例:

@Composable
fun ColumnAlignmentDemo() {
    Row(
        modifier = Modifier.padding(16.dp),
        horizontalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // Start
        AlignmentColumn(
            title = "Start",
            alignment = Alignment.Start
        )
        
        // CenterHorizontally
        AlignmentColumn(
            title = "Center",
            alignment = Alignment.CenterHorizontally
        )
        
        // End
        AlignmentColumn(
            title = "End",
            alignment = Alignment.End
        )
    }
}

@Composable
private fun AlignmentColumn(
    title: String,
    alignment: Alignment.Horizontal
) {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Column(
            modifier = Modifier
                .width(120.dp)
                .background(Color.LightGray)
                .padding(8.dp),
            horizontalAlignment = alignment
        ) {
            Box(
                modifier = Modifier
                    .width(80.dp)
                    .height(30.dp)
                    .background(Color.Red)
            )
            Spacer(modifier = Modifier.height(8.dp))
            Box(
                modifier = Modifier
                    .width(50.dp)
                    .height(30.dp)
                    .background(Color.Green)
            )
            Spacer(modifier = Modifier.height(8.dp))
            Box(
                modifier = Modifier
                    .width(100.dp)
                    .height(30.dp)
                    .background(Color.Blue)
            )
        }
        Text(title, fontSize = 10.sp, color = Color.Gray)
    }
}

3.4 Column 综合使用示例

@Composable
fun ColumnCompleteExample() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(24.dp)
    ) {
        // 示例1:表单布局
        FormExample()
        
        // 示例2:卡片详情
        CardDetailExample()
        
        // 示例3:底部操作栏
        BottomActionExample()
    }
}

@Composable
private fun FormExample() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text(
            text = "登录",
            fontSize = 24.sp,
            fontWeight = FontWeight.Bold
        )
        
        // 用户名输入
        Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
            Text(
                text = "用户名",
                fontSize = 14.sp,
                color = Color.Gray
            )
            OutlinedTextField(
                value = "",
                onValueChange = {},
                modifier = Modifier.fillMaxWidth(),
                placeholder = { Text("请输入用户名") }
            )
        }
        
        // 密码输入
        Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
            Text(
                text = "密码",
                fontSize = 14.sp,
                color = Color.Gray
            )
            OutlinedTextField(
                value = "",
                onValueChange = {},
                modifier = Modifier.fillMaxWidth(),
                placeholder = { Text("请输入密码") },
                visualTransformation = PasswordVisualTransformation()
            )
        }
        
        // 登录按钮
        Button(
            onClick = {},
            modifier = Modifier.fillMaxWidth()
        ) {
            Text("登录")
        }
    }
}

@Composable
private fun CardDetailExample() {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.White, RoundedCornerShape(12.dp))
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        // 标题行
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                text = "订单详情",
                fontSize = 18.sp,
                fontWeight = FontWeight.Bold
            )
            Text(
                text = "已完成",
                fontSize = 14.sp,
                color = Color(0xFF4CAF50)
            )
        }
        
        Divider()
        
        // 信息列表
        Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
            InfoRow(label = "订单号", value = "ORD20240115001")
            InfoRow(label = "下单时间", value = "2024-01-15 14:30")
            InfoRow(label = "支付方式", value = "微信支付")
            InfoRow(label = "配送地址", value = "北京市朝阳区xxx街道")
        }
        
        Divider()
        
        // 金额
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Text("实付金额", color = Color.Gray)
            Text(
                "¥299.00",
                fontWeight = FontWeight.Bold,
                color = Color(0xFFFF5722)
            )
        }
    }
}

@Composable
private fun InfoRow(label: String, value: String) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(label, color = Color.Gray, fontSize = 14.sp)
        Text(value, fontSize = 14.sp)
    }
}

@Composable
private fun BottomActionExample() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button(
            onClick = {},
            modifier = Modifier.fillMaxWidth()
        ) {
            Text("确认提交")
        }
        
        TextButton(onClick = {}) {
            Text("取消")
        }
    }
}

四、参数配置与组合使用

4.1 多参数组合配置

@Composable
fun CombinedParametersExample() {
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(24.dp)
    ) {
        // Row组合示例
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .height(100.dp)
                .background(Color(0xFFE3F2FD)),
            horizontalArrangement = Arrangement.SpaceAround,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text("Item 1")
            Text("Item 2")
            Text("Item 3")
        }
        
        // Column组合示例
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
                .background(Color(0xFFF3E5F5)),
            verticalArrangement = Arrangement.SpaceEvenly,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text("Item A")
            Text("Item B")
            Text("Item C")
        }
    }
}

4.2 嵌套布局

@Composable
fun NestedLayoutExample() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        // 顶部导航栏
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            IconButton(onClick = {}) {
                Icon(Icons.Default.Menu, null)
            }
            Text("首页", fontWeight = FontWeight.Bold)
            IconButton(onClick = {}) {
                Icon(Icons.Default.Search, null)
            }
        }
        
        // 中间内容区
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
                .verticalScroll(rememberScrollState()),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            // 横向滚动内容
            Row(
                modifier = Modifier.horizontalScroll(rememberScrollState()),
                horizontalArrangement = Arrangement.spacedBy(12.dp)
            ) {
                repeat(5) { index ->
                    Card(
                        modifier = Modifier.size(120.dp),
                        colors = CardDefaults.cardColors(
                            containerColor = Color(0xFFBBDEFB)
                        )
                    ) {
                        Box(
                            modifier = Modifier.fillMaxSize(),
                            contentAlignment = Alignment.Center
                        ) {
                            Text("Card $index")
                        }
                    }
                }
            }
            
            // 列表项
            repeat(3) { index ->
                Card(
                    modifier = Modifier.fillMaxWidth(),
                    colors = CardDefaults.cardColors(
                        containerColor = Color(0xFFE8F5E9)
                    )
                ) {
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(16.dp),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Column {
                            Text(
                                "列表项 ${index + 1}",
                                fontWeight = FontWeight.Medium
                            )
                            Text(
                                "描述信息",
                                fontSize = 12.sp,
                                color = Color.Gray
                            )
                        }
                        Icon(Icons.Default.ChevronRight, null)
                    }
                }
            }
        }
        
        // 底部导航栏
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            val items = listOf("首页", "分类", "购物车", "我的")
            items.forEach { item ->
                Column(
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Icon(Icons.Default.Home, null)
                    Text(item, fontSize = 12.sp)
                }
            }
        }
    }
}

4.3 与 Modifier 的配合使用

@Composable
fun ModifierCombinationExample() {
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // 使用 weight 分配空间
        Row(
            modifier = Modifier.fillMaxWidth()
        ) {
            Box(
                modifier = Modifier
                    .weight(1f)
                    .height(50.dp)
                    .background(Color.Red)
            )
            Box(
                modifier = Modifier
                    .weight(2f)
                    .height(50.dp)
                    .background(Color.Green)
            )
            Box(
                modifier = Modifier
                    .weight(1f)
                    .height(50.dp)
                    .background(Color.Blue)
            )
        }
        
        // 使用 padding 和 border
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)
                .border(1.dp, Color.Gray, RoundedCornerShape(8.dp))
                .padding(16.dp),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Text("左侧内容")
            Text("右侧内容")
        }
        
        // 使用 size 和 aspectRatio
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            Box(
                modifier = Modifier
                    .size(80.dp)
                    .background(Color(0xFFFFCDD2), CircleShape)
            )
            Box(
                modifier = Modifier
                    .size(80.dp)
                    .aspectRatio(1f)
                    .background(Color(0xFFC8E6C9), RoundedCornerShape(16.dp))
            )
            Box(
                modifier = Modifier
                    .width(80.dp)
                    .height(60.dp)
                    .background(Color(0xFFBBDEFB))
            )
        }
    }
}

五、RowScope 与 ColumnScope

5.1 Scope 作用域说明

RowScopeColumnScope 提供了在特定布局中使用的专用修饰符。

5.2 RowScope 专属修饰符

@Composable
fun RowScopeDemo() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
            .padding(16.dp)
    ) {
        // weight - 按比例分配剩余空间
        Box(
            modifier = Modifier
                .weight(1f)
                .fillMaxHeight()
                .background(Color.Red)
        )
        
        Box(
            modifier = Modifier
                .weight(2f)
                .fillMaxHeight()
                .background(Color.Green)
        )
        
        Box(
            modifier = Modifier
                .weight(1f)
                .fillMaxHeight()
                .background(Color.Blue)
        )
    }
}

RowScope 可用修饰符:

修饰符作用
Modifier.weight(weight, fill)按比例分配剩余水平空间
Modifier.align(alignment)单独设置垂直方向对齐方式

5.3 ColumnScope 专属修饰符

@Composable
fun ColumnScopeDemo() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        // 固定高度头部
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(60.dp)
                .background(Color(0xFF6200EE))
        )
        
        // weight 分配剩余空间给内容区
        Box(
            modifier = Modifier
                .weight(1f)
                .fillMaxWidth()
                .background(Color(0xFFE3F2FD))
        ) {
            Text(
                "内容区域(自适应高度)",
                modifier = Modifier.align(Alignment.Center)
            )
        }
        
        // 固定高度底部
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(60.dp)
                .background(Color(0xFF4CAF50))
        )
    }
}

ColumnScope 可用修饰符:

修饰符作用
Modifier.weight(weight, fill)按比例分配剩余垂直空间
Modifier.align(alignment)单独设置水平方向对齐方式
Modifier.alignBy(alignmentLine)基于对齐线对齐

5.4 子组件独立对齐

@Composable
fun IndividualAlignmentExample() {
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // Row 中子组件独立对齐
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .height(100.dp)
                .background(Color.LightGray),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                "顶部对齐",
                modifier = Modifier.align(Alignment.Top)
            )
            
            Spacer(modifier = Modifier.width(16.dp))
            
            Text(
                "居中对齐(默认)"
            )
            
            Spacer(modifier = Modifier.width(16.dp))
            
            Text(
                "底部对齐",
                modifier = Modifier.align(Alignment.Bottom)
            )
        }
        
        // Column 中子组件独立对齐
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .height(150.dp)
                .background(Color.LightGray),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(
                "左对齐",
                modifier = Modifier.align(Alignment.Start)
            )
            
            Text(
                "居中对齐(默认)"
            )
            
            Text(
                "右对齐",
                modifier = Modifier.align(Alignment.End)
            )
        }
    }
}

六、常见问题与最佳实践

6.1 布局溢出问题

@Composable
fun OverflowSolutionExample() {
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // 问题:Row内容超出屏幕宽度
        Text("问题:内容溢出", fontWeight = FontWeight.Bold)
        Row {
            repeat(10) {
                Box(
                    modifier = Modifier
                        .size(60.dp)
                        .background(Color.Red)
                )
            }
        }
        
        // 解决方案1:添加水平滚动
        Text("方案1:horizontalScroll", fontWeight = FontWeight.Bold)
        Row(
            modifier = Modifier.horizontalScroll(rememberScrollState())
        ) {
            repeat(10) {
                Box(
                    modifier = Modifier
                        .size(60.dp)
                        .background(Color.Green)
                )
            }
        }
        
        // 解决方案2:使用 weight 分配空间
        Text("方案2:weight 分配", fontWeight = FontWeight.Bold)
        Row(
            modifier = Modifier.fillMaxWidth()
        ) {
            repeat(5) {
                Box(
                    modifier = Modifier
                        .weight(1f)
                        .height(60.dp)
                        .background(Color.Blue)
                )
            }
        }
    }
}

6.2 权重分配技巧

@Composable
fun WeightDistributionExample() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        // 示例1:头部固定,内容自适应,底部固定
        Row(
            modifier = Modifier.fillMaxWidth()
        ) {
            Box(
                modifier = Modifier
                    .width(80.dp)
                    .height(50.dp)
                    .background(Color.Gray),
                contentAlignment = Alignment.Center
            ) {
                Text("固定", color = Color.White)
            }
            
            Box(
                modifier = Modifier
                    .weight(1f)
                    .height(50.dp)
                    .background(Color(0xFF6200EE)),
                contentAlignment = Alignment.Center
            ) {
                Text("自适应", color = Color.White)
            }
            
            Box(
                modifier = Modifier
                    .width(80.dp)
                    .height(50.dp)
                    .background(Color.Gray),
                contentAlignment = Alignment.Center
            ) {
                Text("固定", color = Color.White)
            }
        }
        
        Spacer(modifier = Modifier.height(16.dp))
        
        // 示例2:按比例分配
        Row(
            modifier = Modifier.fillMaxWidth()
        ) {
            Box(
                modifier = Modifier
                    .weight(1f)
                    .height(50.dp)
                    .background(Color.Red),
                contentAlignment = Alignment.Center
            ) {
                Text("1份", color = Color.White)
            }
            
            Box(
                modifier = Modifier
                    .weight(2f)
                    .height(50.dp)
                    .background(Color.Green),
                contentAlignment = Alignment.Center
            ) {
                Text("2份", color = Color.White)
            }
            
            Box(
                modifier = Modifier
                    .weight(3f)
                    .height(50.dp)
                    .background(Color.Blue),
                contentAlignment = Alignment.Center
            ) {
                Text("3份", color = Color.White)
            }
        }
    }
}

6.3 性能优化建议

/**
 * Row/Column 性能优化最佳实践
 */
object LayoutPerformanceTips {
    
    /**
     * 1. 避免过深嵌套
     * 尽量保持布局层级扁平
     */
    @Composable
    fun FlatLayout() {
        // ✅ 推荐:扁平结构
        Row {
            // 直接放置子组件
        }
        
        // ❌ 避免:过深嵌套
        Row {
            Column {
                Row {
                    Column {
                        // 深层嵌套影响性能
                    }
                }
            }
        }
    }
    
    /**
     * 2. 大量数据使用 Lazy 系列
     */
    @Composable
    fun LargeDataList() {
        // ✅ 推荐:LazyRow/LazyColumn
        LazyColumn {
            items(1000) { index ->
                ListItem(index)
            }
        }
        
        // ❌ 避免:直接使用 Column
        Column {
            repeat(1000) { index ->
                ListItem(index)
            }
        }
    }
    
    /**
     * 3. 合理使用 remember 缓存计算
     */
    @Composable
    fun CachedLayout() {
        val arrangement = remember {
            Arrangement.spacedBy(16.dp)
        }
        
        Column(
            verticalArrangement = arrangement
        ) {
            // 子组件
        }
    }
}

6.4 响应式布局

@Composable
fun ResponsiveLayoutExample() {
    // 使用 BoxWithConstraints 获取容器尺寸
    BoxWithConstraints(
        modifier = Modifier.fillMaxSize()
    ) {
        val isWideScreen = maxWidth > 600.dp
        
        if (isWideScreen) {
            // 宽屏:水平排列
            Row(
                modifier = Modifier.fillMaxSize(),
                horizontalArrangement = Arrangement.spacedBy(16.dp)
            ) {
                SidePanel(modifier = Modifier.weight(1f))
                MainContent(modifier = Modifier.weight(2f))
            }
        } else {
            // 窄屏:垂直排列
            Column(
                modifier = Modifier.fillMaxSize(),
                verticalArrangement = Arrangement.spacedBy(16.dp)
            ) {
                SidePanel(modifier = Modifier.height(200.dp))
                MainContent(modifier = Modifier.weight(1f))
            }
        }
    }
}

@Composable
private fun SidePanel(modifier: Modifier = Modifier) {
    Box(
        modifier = modifier.background(Color(0xFFE3F2FD)),
        contentAlignment = Alignment.Center
    ) {
        Text("侧边栏")
    }
}

@Composable
private fun MainContent(modifier: Modifier = Modifier) {
    Box(
        modifier = modifier.background(Color(0xFFF3E5F5)),
        contentAlignment = Alignment.Center
    ) {
        Text("主内容区")
    }
}

七、完整代码示例

7.1 完整页面布局示例

@Composable
fun CompletePageExample() {
    Column(
        modifier = Modifier.fillMaxSize()
    ) {
        // 顶部应用栏
        TopAppBar()
        
        // 可滚动内容区
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
                .verticalScroll(rememberScrollState())
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            // 用户信息卡片
            UserProfileCard()
            
            // 统计数据行
            StatisticsRow()
            
            // 功能菜单网格
            FeatureMenuGrid()
            
            // 最近活动列表
            RecentActivityList()
        }
        
        // 底部导航栏
        BottomNavigationBar()
    }
}

@Composable
private fun TopAppBar() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(56.dp)
            .background(Color(0xFF6200EE))
            .padding(horizontal = 16.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            imageVector = Icons.Default.Menu,
            contentDescription = "Menu",
            tint = Color.White
        )
        Text(
            text = "我的应用",
            color = Color.White,
            fontSize = 20.sp,
            fontWeight = FontWeight.Medium
        )
        Icon(
            imageVector = Icons.Default.Notifications,
            contentDescription = "Notifications",
            tint = Color.White
        )
    }
}

@Composable
private fun UserProfileCard() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.White, RoundedCornerShape(12.dp))
            .padding(16.dp),
        horizontalArrangement = Arrangement.spacedBy(16.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        // 头像
        Box(
            modifier = Modifier
                .size(64.dp)
                .background(Color(0xFFBBDEFB), CircleShape),
            contentAlignment = Alignment.Center
        ) {
            Icon(
                imageVector = Icons.Default.Person,
                contentDescription = null,
                modifier = Modifier.size(32.dp),
                tint = Color(0xFF1976D2)
            )
        }
        
        // 用户信息
        Column(
            modifier = Modifier.weight(1f),
            verticalArrangement = Arrangement.spacedBy(4.dp)
        ) {
            Text(
                text = "张三",
                fontSize = 20.sp,
                fontWeight = FontWeight.Bold
            )
            Text(
                text = "高级会员",
                fontSize = 14.sp,
                color = Color(0xFFFF9800)
            )
            Text(
                text = "zhangsan@example.com",
                fontSize = 12.sp,
                color = Color.Gray
            )
        }
        
        // 编辑按钮
        Icon(
            imageVector = Icons.Default.Edit,
            contentDescription = "Edit",
            tint = Color.Gray
        )
    }
}

@Composable
private fun StatisticsRow() {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        StatisticItem(
            title = "订单",
            value = "128",
            modifier = Modifier.weight(1f)
        )
        StatisticItem(
            title = "收藏",
            value = "56",
            modifier = Modifier.weight(1f)
        )
        StatisticItem(
            title = "优惠券",
            value = "12",
            modifier = Modifier.weight(1f)
        )
        StatisticItem(
            title = "积分",
            value = "3,580",
            modifier = Modifier.weight(1f)
        )
    }
}

@Composable
private fun StatisticItem(
    title: String,
    value: String,
    modifier: Modifier = Modifier
) {
    Column(
        modifier = modifier
            .background(Color.White, RoundedCornerShape(8.dp))
            .padding(12.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        Text(
            text = value,
            fontSize = 20.sp,
            fontWeight = FontWeight.Bold,
            color = Color(0xFF6200EE)
        )
        Text(
            text = title,
            fontSize = 12.sp,
            color = Color.Gray
        )
    }
}

@Composable
private fun FeatureMenuGrid() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            FeatureItem(
                icon = Icons.Default.ShoppingCart,
                title = "购物车",
                modifier = Modifier.weight(1f)
            )
            FeatureItem(
                icon = Icons.Default.Favorite,
                title = "收藏夹",
                modifier = Modifier.weight(1f)
            )
            FeatureItem(
                icon = Icons.Default.LocationOn,
                title = "地址管理",
                modifier = Modifier.weight(1f)
            )
        }
        
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            FeatureItem(
                icon = Icons.Default.History,
                title = "浏览记录",
                modifier = Modifier.weight(1f)
            )
            FeatureItem(
                icon = Icons.Default.Settings,
                title = "设置",
                modifier = Modifier.weight(1f)
            )
            FeatureItem(
                icon = Icons.Default.Help,
                title = "帮助中心",
                modifier = Modifier.weight(1f)
            )
        }
    }
}

@Composable
private fun FeatureItem(
    icon: ImageVector,
    title: String,
    modifier: Modifier = Modifier
) {
    Column(
        modifier = modifier
            .background(Color.White, RoundedCornerShape(8.dp))
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Icon(
            imageVector = icon,
            contentDescription = title,
            tint = Color(0xFF6200EE)
        )
        Text(
            text = title,
            fontSize = 12.sp
        )
    }
}

@Composable
private fun RecentActivityList() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Text(
            text = "最近活动",
            fontSize = 16.sp,
            fontWeight = FontWeight.Bold
        )
        
        repeat(3) { index ->
            ActivityItem(
                title = "活动 ${index + 1}",
                time = "2024-01-${15 + index} 14:30",
                description = "完成了订单 #100${index}"
            )
        }
    }
}

@Composable
private fun ActivityItem(
    title: String,
    time: String,
    description: String
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.White, RoundedCornerShape(8.dp))
            .padding(12.dp),
        horizontalArrangement = Arrangement.spacedBy(12.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color(0xFFE3F2FD), CircleShape),
            contentAlignment = Alignment.Center
        ) {
            Icon(
                imageVector = Icons.Default.CheckCircle,
                contentDescription = null,
                tint = Color(0xFF4CAF50)
            )
        }
        
        Column(
            modifier = Modifier.weight(1f),
            verticalArrangement = Arrangement.spacedBy(2.dp)
        ) {
            Text(
                text = title,
                fontWeight = FontWeight.Medium
            )
            Text(
                text = description,
                fontSize = 12.sp,
                color = Color.Gray
            )
        }
        
        Text(
            text = time,
            fontSize = 11.sp,
            color = Color.LightGray
        )
    }
}

@Composable
private fun BottomNavigationBar() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(56.dp)
            .background(Color.White)
            .padding(horizontal = 16.dp),
        horizontalArrangement = Arrangement.SpaceEvenly,
        verticalAlignment = Alignment.CenterVertically
    ) {
        val items = listOf(
            "首页" to Icons.Default.Home,
            "分类" to Icons.Default.Category,
            "购物车" to Icons.Default.ShoppingCart,
            "我的" to Icons.Default.Person
        )
        
        items.forEach { (title, icon) ->
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.spacedBy(2.dp)
            ) {
                Icon(icon, contentDescription = title)
                Text(title, fontSize = 11.sp)
            }
        }
    }
}

总结

RowColumn 是 Jetpack Compose 中最基础也是最常用的布局容器:

特性RowColumn
排列方向水平垂直
主轴参数horizontalArrangementverticalArrangement
交叉轴参数verticalAlignmenthorizontalAlignment
Scope修饰符weight(), align()weight(), align()

核心要点:

  1. Arrangement 控制主轴上的排列方式(Start、End、Center、SpaceBetween、SpaceAround、SpaceEvenly、spacedBy)

  2. Alignment 控制交叉轴上的对齐方式(Start/Center/End 或 Top/Center/Bottom)

  3. Scope修饰符 可以在子组件级别覆盖容器的对齐设置

  4. Modifier.weight() 用于按比例分配剩余空间

  5. 性能优化:避免过深嵌套,大量数据使用Lazy系列,合理使用remember缓存

掌握这些基础布局容器的使用方法,是构建复杂 Compose 界面的基础。


参考资源