Jetpack Compose中的布局容器(Layout Composable)主要分为几大类,它们各自有不同的定位方式、排列规则和适用场景。

线性布局

row

水平线性排列子组件,子元素从左到右依次摆放

Row(
    modifier=Modifier.fillMaxWidth(),
    horizontalArrangement=Arrangement.SpaceBetween,
    verticalAlignment=Alignment.CenterVertically
){
    Text("左边")
    Button(onClick={}) { Text("中间按钮") }
    Text("右边")
}

Column

垂直线性排列子组件,子元素从上到下依次摆放

Column(
    modifier=Modifier.fillMaxSize(),
    verticalArrangement=Arrangement.Center,
    horizontalAlignment=Alignment.CenterHorizontally
){
    Text("顶部文字")
    Spacer(modifier=Modifier.height(16.dp))
    Image(painter=...,contentDescription=null)
    Text("底部说明")
}

LazyColumn

垂直高效懒加载列表,类似RecyclerView,只渲染可见项

LazyColumn{
    items(100){index->
        Text(
            "第 $index 项",
            modifier=Modifier
                .fillMaxWidth()
                .padding(16.dp)
        )
    }
}

LazyRow

水平懒加载列表,适合横向滚动的卡片或标签

LazyRow(
    contentPadding=PaddingValues(horizontal=16.dp),
    horizontalArrangement=Arrangement.spacedBy(8.dp)
){
    items(listOf("全部","热门","最新","关注")){
        FilterChip(selected=it=="全部",onClick={},label={Text(it)})
    }
}

层叠布局

box

层叠布局,子组件默认重叠在左上角,可通过align或offset控制位置

Box(modifier=Modifier.size(200.dp)){
    Image(
         modifier = Modifier.fillMaxSize(),
         painter = painterResource(id = R.drawable.ic_launcher_foreground),
         contentDescription = null
    )
    Text(
        "叠加文字",
        modifier=Modifier.align(Alignment.BottomEnd).padding(8.dp),
        color=Color.White,
        style=MaterialTheme.typography.labelLarge
    )
}

BoxWithConstraints

带约束信息的Box,能获取父容器的最大/最小宽高,常用于响应式布局

BoxWithConstraints(modifier=Modifier.fillMaxWidth()){
    val isWide= maxWidth>400.dp
    Row{
        Text(if(isWide)"宽屏布局" else "窄屏布局")
        if(isWide)Spacer(Modifier.width(32.dp))
    }
}

网格/瀑布布局

LazyVerticalGrid

垂直网格布局,适合规则的宫格展示

LazyVerticalGrid(
    columns=GridCells.Fixed(3),
    contentPadding=PaddingValues(8.dp),
    verticalArrangement=Arrangement.spacedBy(8.dp),
    horizontalArrangement=Arrangement.spacedBy(8.dp)
){
    items(30){index->
        Card{
            Text(
                "格子 $index",
                modifier=Modifier.padding(16.dp)
            )
        }
    }
}

页面结构

Scaffold

应用标准页面骨架,提供顶部栏、底部栏、浮动按钮、抽屉等结构

Scaffold(
    topBar={TopAppBar(title={Text("标题")})},
    bottomBar={
        NavigationBar{
            NavigationBarItem(
                selected=true,
                onClick={},
                icon={Icon(Icons.Default.Home,"")}
            )
        }
    },
    floatingActionButton={
        FloatingActionButton(onClick={}) {
            Icon(Icons.Default.Add,"")
        }
    }
){innerPadding->
    Column(Modifier.padding(innerPadding)) {
        Text("页面内容区域")
    }
}

约束布局

ConstraintLayout

基于约束的灵活布局,适合复杂相对定位

ConstraintLayout(modifier=Modifier.fillMaxSize()){
    val (title,button,image)=createRefs()
    
    Text("标题",modifier=createRef().constrainAs(title){
        top.linkTo(parent.top,margin=32.dp)
        start.linkTo(parent.start)
        end.linkTo(parent.end)
    })
    
    Button(onClick={},modifier=createRef().constrainAs(button){
        top.linkTo(title.bottom,margin=24.dp)
        start.linkTo(parent.start,margin=32.dp)
    }){
        Text("点击")
    }
    
    Image(painter=...,contentDescription=null,
        modifier=createRef().constrainAs(image){
            top.linkTo(button.bottom,margin=16.dp)
            bottom.linkTo(parent.bottom,margin=32.dp)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
        })
}

内容组件/控件

Text

显示单行或多行纯文本,支持字体、颜色、对齐、溢出处理等样式

Text(
    text = "这是一个示例文本\n支持换行",
    fontSize = 18.sp,
    color = MaterialTheme.colorScheme.primary,
    textAlign = TextAlign.Center,
    maxLines = 2,
    overflow = TextOverflow.Ellipsis,
    modifier = Modifier.padding(16.dp)
)

Button

标准可点击按钮,通常包含文字或图标,支持多种变体(Filled、Outlined、Text)

Button(
    onClick = { /* 点击事件 */ },
    colors = ButtonDefaults.buttonColors(
        containerColor = MaterialTheme.colorScheme.primary
    ),
    modifier = Modifier.padding(8.dp)
) {
    Text("点击我")
}

OutlinedButton

带边框的按钮,视觉上更轻量,常用于次要操作

OutlinedButton(
    onClick = { /* 点击事件 */ },
    modifier = Modifier.size(width = 160.dp, height = 48.dp)
) {
    Text("次要操作")
}

TextButton

纯文字按钮,无背景无边框,最轻量,常用于对话框或工具栏

TextButton(onClick = { /* 点击事件 */ }) {
    Text("取消", color = MaterialTheme.colorScheme.error)
}

IconButton

图标按钮,通常只显示图标,常用于工具栏、卡片操作

IconButton(onClick = { /* 点击事件 */ }) {
    Icon(
        imageVector = Icons.Default.Favorite,
        contentDescription = "收藏",
        tint = Color.Red
    )
}

FloatingActionButton

浮动动作按钮,圆形,通常放在屏幕右下角,用于主要操作

FloatingActionButton(
    onClick = { /* 新建 */ },
    containerColor = MaterialTheme.colorScheme.secondary
) {
    Icon(Icons.Default.Add, contentDescription = "添加")
}

ExtendedFloatingActionButton

带文字的扩展浮动按钮,可显示图标+文字

ExtendedFloatingActionButton(
    text = { Text("新建项目") },
    icon = { Icon(Icons.Default.Add, null) },
    onClick = { /* 点击事件 */ }
)

TextField / OutlinedTextField

单行输入框,支持标签、占位符、前缀/后缀图标、错误提示等

var text by remember { mutableStateOf("") }

OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("请输入用户名") },
    leadingIcon = { Icon(Icons.Default.Person, null) },
    modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp)
)

Image

显示图片,支持本地、网络、资源文件、异步加载(Coil/Glide)

AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = "示例图片",
    modifier = Modifier
        .size(200.dp)
        .clip(CircleShape),
    contentScale = ContentScale.Crop
)

Icon

显示矢量图标或图片,支持 tint 着色

Icon(
    imageVector = Icons.Default.Star,
    contentDescription = "星级",
    tint = Color.Yellow,
    modifier = Modifier.size(32.dp)
)

Checkbox

复选框控件,用于多选场景

var checked by remember { mutableStateOf(false) }

Checkbox(
    checked = checked,
    onCheckedChange = { checked = it }
)

Text(if(checked) "已选中" else "未选中")

Switch

开关控件,用于开启/关闭设置

var checked by remember { mutableStateOf(true) }

Switch(
    checked = checked,
    onCheckedChange = { checked = it }
)

Slider

滑动条,用于选择数值范围

var sliderPosition by remember { mutableFloatStateOf(0f) }

Slider(
    value = sliderPosition,
    onValueChange = { sliderPosition = it },
    valueRange = 0f..100f,
    steps = 9
)

Text("当前值: ${sliderPosition.toInt()}")

CircularProgressIndicator / LinearProgressIndicator

进度指示器,用于显示加载中或进度

CircularProgressIndicator(
    modifier = Modifier.size(48.dp),
    color = MaterialTheme.colorScheme.primary
)

LinearProgressIndicator(
    progress = { 0.7f },
    modifier = Modifier.fillMaxWidth().padding(16.dp)
)