Jetpack Compose 可讓您在設計及建構應用程式 UI 時更加得心應手。Compose 會透過下列方式將狀態轉換為 UI 元素:
- 元素組合
- 元素的版面配置
- 繪製元素
本文件將重點放在元素的版面配置,說明 Compose 提供的部分建構區塊,以協助您安排 UI 元素的版面配置。
Compose 的版面配置目標
Jetpack Compose 導入版面配置系統有兩個主要目標:
可組合函式的基本概念
可組合函式是 Compose 的基本構成要素。可組合函式是會發出 Unit
的函式,用於描述使用者介面的部分元件。這種函式會接受部分輸入內容,並產生畫面上顯示的內容。如要進一步瞭解可組合項,請參閱 Compose 心理模型說明文件。
可組合函式可能會輸出多個 UI 元素。不過,如果您未提供如何安排這些元素的指引,Compose 可能會以您不想要的方式安排元素位置。舉例來說,以下程式碼會產生兩個文字元素:
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
如果您沒有提供想要的排列方式,Compose 會將文字元素互相堆疊在一起,以致文字無法閱讀:
Compose 提供一系列現成可用的版面配置,協助您安排 UI 元素,進而自行定義更特殊的版面配置。
標準版面配置元件
在多數情況下,您可以直接使用 Compose 的標準版面配置元素。
使用 Column
將項目直向排列在畫面上。
@Composable fun ArtistCardColumn() { Column { Text("Alfred Sisley") Text("3 minutes ago") } }
同樣地,使用 Row
將項目橫向排列在畫面上。Column
和 Row
都支援所含元素的對齊設定。
@Composable fun ArtistCardRow(artist: Artist) { Row(verticalAlignment = Alignment.CenterVertically) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { Text(artist.name) Text(artist.lastSeenOnline) } } }
如要將元素放在另一個元素上,請使用 Box
。Box
也支援所含元素的特定對齊設定。
@Composable fun ArtistAvatar(artist: Artist) { Box { Image(bitmap = artist.image, contentDescription = "Artist image") Icon(Icons.Filled.Check, contentDescription = "Check mark") } }
您通常只需要使用這些建構區塊。您可以自行編寫可組合函式,將這些版面配置結合成更精巧的版面配置,以符合應用程式的需求。
如要在 Row
內設定子項的位置,請設定 horizontalArrangement
和 verticalAlignment
引數。如要針對 Column
進行這項設定,則應設定 verticalArrangement
和 horizontalAlignment
引數:
@Composable fun ArtistCardArrangement(artist: Artist) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { /*...*/ } } }
版面配置模型
在版面配置模型中,UI 樹狀結構是透過單次傳遞完成版面配置。系統會先要求每個節點自我測量,接著對任何子項進行遞迴測量,並將大小限制向下傳遞至樹狀結構的子項。接下來,系統會設定分葉節點的大小和位置,並將解析後的大小和位置指示向上傳遞回樹狀結構。
簡單來說,測量順序是父項先子項後,但設定大小和位置的順序則是子項先父項後。
我們來深入分析下列 SearchResult
函式。
@Composable fun SearchResult() { Row { Image( // ... ) Column { Text( // ... ) Text( // ... ) } } }
這個函式會產生以下 UI 樹狀結構。
SearchResult
Row
Image
Column
Text
Text
在 SearchResult
範例中,系統會按照以下順序安排 UI 樹狀結構的版面配置:
- 系統要求根節點
Row
進行測量。 - 根節點
Row
要求其第一個子項Image
進行測量。 Image
是分葉節點 (也就是不含任何子項),因此會回報大小並傳回位置指示。- 根節點
Row
要求其第二個子項Column
進行測量。 Column
節點要求其第一個Text
子項進行測量。- 第一個
Text
節點是分葉節點,因此會回報大小並傳回位置指示。 Column
節點要求其第二個Text
子項進行測量。- 第二個
Text
節點是分葉節點,因此會回報大小並傳回位置指示。 Column
節點完成測量並設定其子項的大小和位置後,現在可以決定本身的大小和位置。- 根節點
Row
完成測量並設定其子項的大小和位置後,現在可以決定本身的大小和位置。
成效
Compose 僅會測量子項一次,藉此提升效能。單次傳遞測量有助於提升效能,可讓 Compose 有效處理深層 UI 樹狀結構。如果某個元素測量其子項兩次,而該子項要測量其每個子項兩次 (以此類推),則每次要配置整個 UI 都必須執行大量工作,導致難以維持應用程式效能。
如果版面配置基於某個理由需要多次測量,Compose 為此提供了「內建函式測量」特殊系統。如要進一步瞭解這項功能,請參閱「Compose 版面配置中的內建函式測量資料」。
由於測量和位置設定是版面配置傳遞的不同子階段,因此僅會影響項目位置 (而不是測量) 的任何變更都能獨立執行。
在版面配置中使用修飾符
如「Compose 修飾符」一文中所述,您可以使用修飾符裝飾或擴增可組合項。修飾符是自訂版面配置的必要選項。舉例來說,我們在此透過鏈結數個修飾符來自訂 ArtistCard
:
@Composable fun ArtistCardModifiers( artist: Artist, onClick: () -> Unit ) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ } Spacer(Modifier.size(padding)) Card( elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), ) { /*...*/ } } }
請注意,以上程式碼將多個不同的修飾符函式搭配使用。
clickable
會讓可組合項對使用者輸入內容產生回應並顯示漣漪效果。padding
會在元素周圍放置空格。fillMaxWidth
提供可組合的父項寬度上限。size()
會指定元素的偏好寬度和高度。
可捲動版面配置
如要進一步瞭解可捲動版面配置,請參閱 Compose 手勢說明文件。
如要查看各種清單和 Lazy 清單,請參閱 Compose 清單說明文件。
回應式版面配置
設計版面配置時應將不同螢幕方向和板型規格大小列入考量。Compose 提供一些內建機制,方便您配合各種螢幕設定調整可組合的版面配置。
限制
為了得知來自父項的限制,並據以設計版面配置,建議您使用 BoxWithConstraints
。測量限制可以在內容 lambda 的範圍中取得。您可以利用這些測量限制,針對不同的螢幕設定組合不同的版面配置:
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
以版位為基礎的版面配置
Compose 提供各式各樣以Material Design為基礎,且包含 androidx.compose.material:material
依附元件的可組合項 (在 Android Studio 中建立 Compose 專案時提供),讓您輕鬆建構 UI。Drawer
、FloatingActionButton
和 TopAppBar
等元素應有盡有。
Material 元件會大量利用「Slot API」,Compose 會採用這個模式將自訂圖層帶入可組合項上方。這種方法使得元件更具彈性,因為元件會接受可自行設定的子項元素,而不須揭露子項的所有設定參數。版位會在 UI 中留下空白空間,讓開發人員視需要填入項目。舉例來說,您可以在 TopAppBar
中自訂下列版位:
可組合函式通常會採用 content
可組合 lambda ( content: @Composable
() -> Unit
)。Slot API 會公開特定用途適用的多個 content
參數。例如,您可以利用 TopAppBar
提供 title
、navigationIcon
和 actions
的內容。
舉例來說,Scaffold
可讓您使用基本的 Material Design 版面配置結構來實作 UI。Scaffold
為最常用的頂層 Material 元件提供版位,例如 TopAppBar
、BottomAppBar
、FloatingActionButton
和 Drawer
。只要使用 Scaffold
,即可輕鬆確保這些元件放置在正確的位置,且能互相搭配正常運作。
@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Compose 修飾符
- 適用於 Jetpack Compose 的 Kotlin
- Material Design 元件和版面配置