採用格線的寬版經典資訊卡版面配置

四星級評等圖示

TV 應用程式設計指南定義了一種稱為「寬版經典資訊卡」的資訊卡變化版本,可並排顯示圖片和說明內容區塊。為電視螢幕建構複雜的二維版面配置時,如果使用傳統的座標定位,或深度巢狀結構的 Row 和 Column 容器,程式碼可能會難以閱讀、維護和重構。寬版經典卡片是 Jetpack Compose Grid API 的理想用途,可協助您使用語意、使用者定義的 2D 版面配置區域,清楚地並排排列元素。

寬版經典資訊卡元件規格,顯示五個命名版面配置區域:圖片、標題、副標題、說明和額外文字。
圖 1:寬版經典資訊卡有五個命名區域:圖片區域和內容區塊中的四個文字區域。

最佳做法

使用 Grid 實作資訊卡版面配置。使用 Grid 容器可將實體版面配置尺寸與子項項目位置分離,提高程式碼可讀性。請使用 area 函式定義語意命名區域,並使用 gridItem 修飾符放置子項可組合項,而不是依賴確切的軌道索引。結合彈性的軌道大小 (例如 GridTrackSize.Auto 和 minmax(0.dp, 1.fr)) 和精確的軌道間距 (gap(row = 8.dp, column = 16.dp)),以清晰且穩健的方式整理複雜的並排資訊卡元件。

要件

  • Grid:Jetpack Compose 中的 2D 容器版面配置,可根據設定 lambda 將子項可組合項排列成列和欄
  • gridItem:Modifier 擴充功能,可將子 UI 元素與 Grid 版面配置中特定命名的 areaId 建立關聯
  • area:GridConfigurationScope 中的設定 DSL 函式,可將語意 areaId 對應至特定列和欄的跨度或範圍
  • Card:Material Design 容器可組合項,可將相關 UI 元素和樣式分組
  • GridTrackSize.MinMax:定義資料列或資料欄維度彈性界限 (min 和 max) 的軌道大小屬性
  • GridTrackSize.Auto:軌道大小調整屬性,可自動調整列或欄軌道的大小,以符合內容 (column(GridTrackSize.Auto))
  • gap:設定函式,用於指定格線軌道之間的垂直 (row) 和水平 (column) 間距

步驟

定義區域 ID、設定格線軌跡和區域,然後放置子項可組合項。

1. 定義語意區域 ID

首先,請在寬版經典卡片版面配置中,建立區域的類型安全表示法。enum 類別可避免字串拼寫錯誤,並在對應軌道和放置子項項目時提供編譯時間安全性。

enum class CardArea {
    Image,
    Title,
    Subtitle,
    Description,
    ExtraText,
}

2. 設定 2D 格線軌跡和命名區域

在 Grid 可組合函式的 config lambda 中,定義構成資訊卡結構的欄和列。圖片欄請使用 GridTrackSize.Auto,這樣就能完整包覆縮圖寬度。請在內容欄使用 minmax(0.dp, 1.fr),讓內容欄能彈性擴展至資訊卡的剩餘寬度。使用 gap(row = 8.dp, column = 16.dp) 指定軌道間距。使用 area 函式,將 CardArea 識別碼對應至實體軌道座標。

Grid(
    config = {
        // Define columns: left column for image, right for content
        column(GridTrackSize.Auto)
        column(minmax(0.dp, 1.fr))

        // Define row tracks for the vertical content stack
        row(GridTrackSize.Auto)
        row(GridTrackSize.Auto)
        row(GridTrackSize.Auto)
        row(GridTrackSize.Auto)

        // Map semantic identifiers to grid coordinates and spans
        area(CardArea.Image, row = 1, column = 1, rowSpan = 4)
        area(CardArea.Title, row = 1, column = 2)
        area(CardArea.Subtitle, row = 2, column = 2)
        area(CardArea.Description, row = 3, column = 2)
        area(CardArea.ExtraText, row = 4, column = 2)

        gap(row = 8.dp, column = 16.dp)
    }
) {
    // Child elements placed in Step 3
}

3. 使用 gridItem 修飾符放置子項可組合函式

設定好軌道和區域後,請使用 gridItem 修飾符,純粹依語意意圖放置每個子項 UI 元素。您可以依任何順序宣告子項可組合項。Grid 容器會自動將每個元素直接放置在指派的 2D 區域中。

@Composable
fun WideClassicCard(
    imageContent: @Composable () -> Unit,
    title: String,
    subtitle: String,
    description: String,
    extraText: String,
    modifier: Modifier = Modifier,
) {
    Card(modifier = modifier) {
        Grid(
            config = {
                // Define columns: left column for image, right for content
                column(GridTrackSize.Auto)
                column(minmax(0.dp, 1.fr))

                // Define row tracks for the vertical content stack
                row(GridTrackSize.Auto)
                row(GridTrackSize.Auto)
                row(GridTrackSize.Auto)
                row(GridTrackSize.Auto)

                // Map semantic identifiers to grid coordinates and spans
                area(CardArea.Image, row = 1, column = 1, rowSpan = 4)
                area(CardArea.Title, row = 1, column = 2)
                area(CardArea.Subtitle, row = 2, column = 2)
                area(CardArea.Description, row = 3, column = 2)
                area(CardArea.ExtraText, row = 4, column = 2)

                gap(row = 8.dp, column = 16.dp)
            },
        ) {
            Box(modifier = Modifier.gridItem(CardArea.Image)) {
                imageContent()
            }
            Text(
                text = title,
                style = MaterialTheme.typography.titleLarge,
                modifier = Modifier
                    .gridItem(CardArea.Title)
                    .padding(top = 16.dp, end = 16.dp),
            )

            Text(
                text = subtitle,
                style = MaterialTheme.typography.titleMedium,
                modifier = Modifier
                    .gridItem(CardArea.Subtitle)
                    .padding(end = 16.dp),
            )

            Text(
                text = description,
                style = MaterialTheme.typography.bodyMedium,
                modifier = Modifier
                    .gridItem(CardArea.Description)
                    .padding(end = 16.dp),
            )

            Text(
                text = extraText,
                style = MaterialTheme.typography.labelSmall,
                modifier = Modifier
                    .gridItem(CardArea.ExtraText)
                    .padding(bottom = 16.dp, end = 16.dp),
            )
        }
    }
}

結果

使用 Grid 和命名區域整理寬版經典卡片,即可清楚區分實體版面配置軌道、區域座標和子項可組合項位置。這種結構可讓版面配置易於閱讀和維護,同時遵循 TV 應用程式設計指南,並排顯示縮圖和說明元件。

其他資源