Android Compose UI 網格佈局 (LazyVerticalGrid)

要製作相簿、商品列表等網格介面,我們使用 LazyVerticalGrid

基礎用法 (GridCells)

我們需要指定 columns 參數來決定網格的欄數。

固定欄數 (Fixed)

LazyVerticalGrid(
    columns = GridCells.Fixed(3), // 固定 3 欄
    verticalArrangement = Arrangement.spacedBy(4.dp),
    horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
    items(100) { index ->
        MyGridItem(index)
    }
}

適應性欄數 (Adaptive)

這是更推薦的做法。我們指定每個項目的最小寬度,Compose 會根據螢幕寬度自動計算能塞下幾欄。 例如:平板上可能顯示 5 欄,手機上顯示 2 欄。

LazyVerticalGrid(
    columns = GridCells.Adaptive(minSize = 120.dp), // 每個項目至少 120dp
    modifier = Modifier.fillMaxSize()
) {
    items(photos) { photo ->
        PhotoItem(photo)
    }
}

合併儲存格 (Span)

有時候我們希望某些項目橫跨多欄(例如廣告橫幅)。這可以使用 itemsspan 參數。

LazyVerticalGrid(columns = GridCells.Fixed(3)) {
    // 橫跨 3 欄的 Header
    item(span = { GridItemSpan(3) }) {
        HeaderBanner()
    }
    
    // 一般項目 (預設跨 1 欄)
    items(items) { item ->
        ProductCard(item)
    }
    
    // 特定項目橫跨 2 欄
    item(span = { GridItemSpan(2) }) {
        WideCard()
    }
}

Staggered Grid (瀑布流)

如果項目高度不固定(如 Pinterest 牆),可以使用 LazyVerticalStaggeredGrid

LazyVerticalStaggeredGrid(
    columns = StaggeredGridCells.Fixed(2),
    verticalItemSpacing = 4.dp,
    horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
    items(images) { image ->
        // 每個圖片依據自己的長寬比顯示,不會被裁切
        AsyncImage(
            model = image.url,
            contentScale = ContentScale.Crop,
            modifier = Modifier.fillMaxWidth().wrapContentHeight()
        )
    }
}

小結

LazyVerticalGrid 讓建立複雜的網格佈局變得輕而易舉。記得優先使用 GridCells.Adaptive 來支援各種螢幕尺寸,這是實踐 Responsive Design 的最佳方式。