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

四星評等圖示

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

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

最佳做法

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

要件

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

步驟

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

1. 定義語意區域 ID

首先,在 Wide 傳統資訊卡版面配置中,建立區域的型別安全表示法。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 和命名區域整理 Wide 傳統資訊卡,即可清楚分隔實體版面配置軌、區域座標和子項可組合項目的放置位置。這個結構可讓版面配置易於閱讀和維護,同時遵循並排顯示縮圖和說明元件的 TV 應用程式設計指南。

其他資源