You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中实现四个等大卡片的网格布局?

Jetpack Compose 2x2等大卡片布局问题修复

我是Jetpack Compose新手,正在跟随Android Studio的Jetpack Compose课程完成布局练习,需要实现一个2行2列的四个等大卡片网格布局(目标效果如下),但试了多种方式都没达到预期,当前效果和目标不符,请求排查解决。

目标布局效果:
目标布局效果

当前布局效果:
当前布局效果

我的代码如下:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            CardTheme {
                Surface(
                    modifier = Modifier.fillMaxSize()
                ){
                    MainScreen()
                }

            }
        }
    }
}


@Composable
fun MainScreen(){
    Column(
        modifier = Modifier.fillMaxSize()
            .padding(16.dp)
    ) {
        Row(
            modifier = Modifier
                .weight(1f)
                .fillMaxSize(),

        ) {
            Card(
                title = "Titulo",
                description = "Descriçao",
                backGroundColor = Color(0xFFEADDFF),
                modifier = Modifier.weight(1f)
                    .fillMaxHeight()

            )
            Card(
                title = "Titulo 2",
                description = "Descrição 2",
                backGroundColor = Color(0xFFD0BCFF),
                modifier = Modifier
                    .weight(1f)
                    .fillMaxHeight()
            )

        }
        Row (
            modifier = Modifier
                .weight(1f)
                .fillMaxWidth(),
        ){
            Card(
                title = "Titulo 3",
                description = "Descrição 3",
                backGroundColor = Color(0xFFB69DF8),
                modifier = Modifier.weight(1f)
                    .fillMaxHeight()
            )
            Card(
                title = "Titulo 4",
                description = "Descrição 4",
                backGroundColor = Color(0xFFF6EDFF),
                modifier = Modifier.weight(1f)
                    .fillMaxHeight()
            )

        }


    }

}


@Composable
private fun Card(
    title: String,
    description: String,
    backGroundColor: Color,
    modifier: Modifier
){
    Column(
        modifier = Modifier
            .padding(16.dp)
            .background(backGroundColor),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = title,
            modifier = Modifier.padding(bottom = 16.dp),
            fontWeight = FontWeight.Bold
        )
        Text(
            text = description,
            textAlign = TextAlign.Justify
        )
    }
}

问题点分析

  1. 自定义Card组件未继承外部Modifier:内部直接使用Modifier.padding(16.dp).background(...),完全覆盖了外部传入的weight(1f)、fillMaxHeight()等布局属性,导致卡片无法填充Row分配的空间。
  2. 第一行Row布局错误:使用fillMaxSize()会让第一行Row占满整个屏幕高度,第二行Row被挤压到极小区域。
  3. 卡片未填充可用空间:缺少fillMaxSize()设置,卡片无法铺满Row分配的宽高。
  4. 背景与padding顺序颠倒:先加padding再设置background,会导致padding区域没有背景色,和目标效果的卡片样式不符。

修正后的代码

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            CardTheme {
                Surface(
                    modifier = Modifier.fillMaxSize()
                ){
                    MainScreen()
                }
            }
        }
    }
}

@Composable
fun MainScreen(){
    Column(
        modifier = Modifier.fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp) // 两行卡片间添加间距
    ) {
        Row(
            modifier = Modifier
                .weight(1f)
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(16.dp) // 两列卡片间添加间距
        ) {
            Card(
                title = "Titulo",
                description = "Descriçao",
                backGroundColor = Color(0xFFEADDFF),
                modifier = Modifier.weight(1f).fillMaxSize()
            )
            Card(
                title = "Titulo 2",
                description = "Descrição 2",
                backGroundColor = Color(0xFFD0BCFF),
                modifier = Modifier.weight(1f).fillMaxSize()
            )
        }
        Row (
            modifier = Modifier
                .weight(1f)
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(16.dp)
        ){
            Card(
                title = "Titulo 3",
                description = "Descrição 3",
                backGroundColor = Color(0xFFB69DF8),
                modifier = Modifier.weight(1f).fillMaxSize()
            )
            Card(
                title = "Titulo 4",
                description = "Descrição 4",
                backGroundColor = Color(0xFFF6EDFF),
                modifier = Modifier.weight(1f).fillMaxSize()
            )
        }
    }
}

@Composable
private fun Card(
    title: String,
    description: String,
    backGroundColor: Color,
    modifier: Modifier = Modifier // 给Modifier设置默认值,提升灵活性
){
    Column(
        modifier = modifier
            .background(backGroundColor) // 先设置背景色,覆盖整个卡片区域
            .padding(16.dp), // 再添加内边距,保证内容与卡片边缘有间隙
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = title,
            modifier = Modifier.padding(bottom = 16.dp),
            fontWeight = FontWeight.Bold
        )
        Text(
            text = description,
            textAlign = TextAlign.Center // 调整为居中对齐,匹配目标效果
        )
    }
}

关键修改说明

  • 继承外部Modifier:将传入的modifier作为基础,叠加background和padding,确保外部布局属性生效。
  • 修正Row布局:移除第一行Row的fillMaxSize(),改用fillMaxWidth()+weight(1f)让两行平分Column的可用高度。
  • 添加卡片间距:通过spacedBy(16.dp)实现卡片间的间隙,和目标效果一致。
  • 强制填充空间:给每个Card添加fillMaxSize(),确保卡片铺满所在Row分配的全部宽高。
  • 调整背景与padding顺序:先设置背景色再添加内边距,让padding区域也显示背景色。

内容的提问来源于stack exchange,提问作者Gustavo Oliveira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:08:13