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

如何在Jetpack Compose中用LazyColumn实现类LazyVerticalGrid布局

在LazyColumn中混合实现两格/三格网格布局

要在LazyColumn里先展示一行两格的分类,再展示一行三格的商品,核心思路是以LazyColumn作为纵向滚动容器,在内部嵌套Row实现每行的多格布局,通过数据分组和权重分配保证格子均分宽度,具体实现如下:

实现步骤与代码示例

1. 定义数据类

先定义分类和商品的数据结构:

data class Category(val id: Int, val name: String, val iconRes: Int)
data class Product(val id: Int, val name: String, val price: String, val imgRes: Int)

2. 主布局实现

在LazyColumn中拆分分类和商品区域,分别处理数据分组:

@Composable
fun MixedGridInLazyColumn() {
    // 模拟测试数据
    val categories = listOf(
        Category(1, "分类1", R.drawable.ic_category1),
        Category(2, "分类2", R.drawable.ic_category2),
        Category(3, "分类3", R.drawable.ic_category3),
        Category(4, "分类4", R.drawable.ic_category4)
    )
    val products = listOf(
        Product(1, "商品1", "¥99", R.drawable.ic_product1),
        Product(2, "商品2", "¥199", R.drawable.ic_product2),
        Product(3, "商品3", "¥299", R.drawable.ic_product3),
        Product(4, "商品4", "¥399", R.drawable.ic_product4),
        Product(5, "商品5", "¥499", R.drawable.ic_product5),
        Product(6, "商品6", "¥599", R.drawable.ic_product6),
        Product(7, "商品7", "¥699", R.drawable.ic_product7)
    )

    // 将数据按每行数量分组:分类每2个一组,商品每3个一组
    val groupedCategories = categories.chunked(2)
    val groupedProducts = products.chunked(3)

    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // 分类标题
        item {
            Text(
                text = "分类",
                fontSize = 20.sp,
                fontWeight = FontWeight.Bold,
                modifier = Modifier.padding(bottom = 8.dp)
            )
        }

        // 分类区域:一行两格
        items(groupedCategories) { rowItems ->
            Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
                rowItems.forEach { CategoryItem(it) }
                // 处理最后一行不足2个的情况,补占位符保证布局对齐
                if (rowItems.size < 2) {
                    Spacer(modifier = Modifier.weight(1f))
                }
            }
        }

        // 商品标题
        item {
            Text(
                text = "商品",
                fontSize = 20.sp,
                fontWeight = FontWeight.Bold,
                modifier = Modifier.padding(top = 16.dp, bottom = 8.dp)
            )
        }

        // 商品区域:一行三格
        items(groupedProducts) { rowItems ->
            Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                rowItems.forEach { ProductItem(it) }
                // 补占位符,确保每行布局对齐
                repeat(3 - rowItems.size) {
                    Spacer(modifier = Modifier.weight(1f))
                }
            }
        }
    }
}

3. 子项布局实现

分别实现分类和商品的子项UI:

@Composable
fun CategoryItem(category: Category) {
    Column(
        modifier = Modifier
            .weight(1f)
            .aspectRatio(1f) // 保持正方形比例
            .background(Color.LightGray, RoundedCornerShape(8.dp))
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Icon(
            painter = painterResource(id = category.iconRes),
            contentDescription = category.name,
            modifier = Modifier.size(40.dp)
        )
        Spacer(modifier = Modifier.height(8.dp))
        Text(text = category.name)
    }
}

@Composable
fun ProductItem(product: Product) {
    Column(
        modifier = Modifier
            .weight(1f)
            .background(Color.LightGray, RoundedCornerShape(8.dp))
            .padding(12.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(id = product.imgRes),
            contentDescription = product.name,
            modifier = Modifier
                .size(80.dp)
                .clip(RoundedCornerShape(4.dp)),
            contentScale = ContentScale.Crop
        )
        Spacer(modifier = Modifier.height(8.dp))
        Text(text = product.name, fontSize = 14.sp, maxLines = 1)
        Spacer(modifier = Modifier.height(4.dp))
        Text(text = product.price, fontSize = 16.sp, color = Color.Red)
    }
}

关键要点说明

  • 数据分组:用chunked(n)方法把原始数据拆分成每行n个的子列表,LazyColumn的items每次加载一行的数据
  • 宽度均分:子项通过Modifier.weight(1f)自动均分所在Row的宽度,保证同一行的格子大小一致
  • 布局对齐:添加占位符处理最后一行数据不足的情况,避免布局错位
  • 比例控制:分类项用aspectRatio(1f)保持正方形,商品项可根据需求调整尺寸比例

内容的提问来源于stack exchange,提问作者Shiva s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:07:32