格線中的延遲清單

四星評等圖示

Grid 可組合函式會建立結構性二維畫面版面配置。 Grid 會使用明確定義的軌道 (列和欄) 和間距,定義回應式版面配置結構,做為 UI 的基礎架構。

由於 Grid 是結構性容器,而非延遲載入容器,因此您必須明確定義放置在其中的每個元素,而不會在捲動時回收項目。因此,直接在 Grid 中算繪大型或動態資料集時,所有項目都會同時組合,可能會造成效能瓶頸。

如要在結構化螢幕版面配置中顯示大量資料集合,請在 Grid 儲存格中嵌入延遲載入元件,例如 LazyColumnLazyRow。但請注意:彈性軌道 (具有 1.fr 等規格) 會查詢子項元素的內建大小。由於 SubcomposeLayout 不支援本質測量傳遞,因此在彈性軌道中放置延遲清單會導致 IllegalStateException 損毀。如要在彈性格線軌道中安全地放置延遲清單,您必須使用 GridTrackSize.MinMax 大小 (例如 minmax(0.dp, 1.fr)) 略過內建測量傳遞。

畫面版面配置,包含頂端的標題、主要內容區域中可捲動的項目清單,以及底部的註腳。
圖 1. 結構化畫面配置,包含標頭、頁尾和內嵌的 LazyColumn 內容。

最佳做法

  • 使用延遲清單,而非大型明確迴圈:如要在結構化 Grid 中顯示大型或動態資料集,請在特定格線儲存格內嵌入延遲元件 (通常是 LazyColumnLazyRow),而非針對項目建立大型明確迴圈,因為 Grid 不會回收項目,且最多只能有 1000 個軌道。
  • 使用 MinMax 追蹤延遲清單的大小:由於 LazyColumnLazyRow 不支援內建測量傳遞 (請參閱 SubcomposeLayout),請在託管延遲元件的彈性軌上使用 GridTrackSize.MinMax,安全地略過內建測量。

要件

  • Grid:可組合的版面配置,可將項目放置在以明確的列和欄軌設定的二維格線結構中。
  • LazyColumn:垂直捲動清單,只會組合及回收目前顯示在畫面上的項目。
  • GridTrackSize.MinMax:追蹤大小屬性,可定義彈性界線 (minmax),安全地代管延遲載入的元件,不會觸發執行階段測量當機。
  • gridItem:Compose Modifier 擴充功能,可將子項 UI 元素指派給 Grid 內的特定儲存格或具名區域。

步驟

定義語意區域 ID、使用 minmax 大小設定格線軌,確保與延遲清單相容,並在格線內容區域內嵌入 LazyColumn,即可建構畫面版面配置。

1. 設定格線軌和命名區域

建立 enum 類別,代表螢幕版面配置的不同區域,並為版面配置軌和具名區域定義 GridConfigurationScope lambda。針對標頭和頁尾列使用 GridTrackSize.MaxContent,以符合內容尺寸,並針對主機的內容軌使用 minmax(0.dp, 1.fr),將延遲清單配置為彈性空間,而不查詢不支援的內建測量值:

enum class ScreenArea {
    Header,
    Content,
    Footer
}


val lazyConfig: GridConfigurationScope.() -> Unit = {
    column(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)
    row(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)

    area(ScreenArea.Header, row = 1, column = 1)
    area(ScreenArea.Content, row = 2, column = 1)
    area(ScreenArea.Footer, row = 3, column = 1)
    gap(8.dp)
}

2. 在格線中放置靜態元件

在可組合函式中,將 lazyConfig 傳遞至 Grid 容器。在 content lambda 內,放置靜態元件 (HeaderFooter),並使用 Modifier.gridItem() 搭配各自的區域 ID 來放置這些元件。

3. 在內容區域中嵌入 LazyColumn

在內容儲存格中,使用 Modifier.gridItem(ScreenArea.Content) 嵌入 LazyColumn。 由於內容軌是在步驟 1 中使用 minmax(0.dp, 1.fr) 設定,因此 LazyColumn 可以安全地測量及回收捲動中的項目,而不必查詢不支援的內建維度:

@Composable
fun GridWithLazyColumn(
    modifier: Modifier = Modifier,
    items: List<String> = emptyList(),
) {
    Grid(
        modifier = modifier.fillMaxSize(),
        config = lazyConfig
    ) {
        Text("Header", Modifier.gridItem(ScreenArea.Header).padding(16.dp))
        Text("Footer", Modifier.gridItem(ScreenArea.Footer).padding(16.dp))

        // LazyColumn placed in the content area for large datasets
        LazyColumn(
            modifier = Modifier
                .gridItem(ScreenArea.Content)
                .fillMaxSize(),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(items) { item ->
                Text(item, Modifier.padding(16.dp))
            }
        }
    }
}

結果

畫面版面配置現在會使用 Grid API 定義整體二維頁面結構,同時在具有 minmax 大小的彈性軌道中嵌入 LazyColumn,有效回收清單項目並避免執行階段例外狀況。

其他資源