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