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
首先,在 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 應用程式設計指南。