本頁面會概略說明構成 Jetpack Compose 的架構層和基礎原則,並提供這項設計的重要概念。
Jetpack Compose 並非單一單體式專案;是由多個模組結合而成,以組成完整的堆疊。瞭解構成 Jetpack Compose 的各種不同模組,您就能:
- 使用適當的抽象層建構您的應用程式或程式庫
- 瞭解何時可以「下滑」到層級較低的位置,進一步自訂或自訂
- 盡可能減少依附元件
圖層
Jetpack Compose 的主要層如下:
圖 1. Jetpack Compose 的主要層。
每一層都是以較低層級建構而成,結合多項功能以建立較高層級的元件。每一層都會建構在較低層的公開 API 上,以驗證模組邊界,並視需求取代任何圖層。現在,讓我們從左下角開始分析這些圖層。
- 執行階段
- 這個模組提供 Compose 執行階段的基礎知識,例如
remember
、mutableStateOf
}@Composable
註解和SideEffect
。如果您只需要撰寫 樹狀結構的樹狀結構功能 (而非 UI 功能),考慮直接在這個層建構。 - UI
- UI 層由多個模組 (
ui-text
、ui-graphics
、ui-tooling
等) 組成。這些模組實作 UI 工具包的基礎知識,例如LayoutNode
、Modifier
、輸入處理常式、自訂版面配置和繪圖。如果您只需要 UI 工具包的基本概念,可以考慮在這個層上建構內容。 - Foundation
- 這個模組提供適用於 Compose UI 的設計系統通用建構模塊,例如
Row
和Column
、LazyColumn
、辨識特定手勢等。請考慮在基礎層上建構自己的設計系統。 - 材料
- 這個模組提供適用於 Compose UI 的質感設計系統實作程序,提供質感系統、樣式化元件、波浪圖示、圖示。在應用程式中使用 Material Design 時,請建構這個圖層。
設計原則
Jetpack Compose 的指導原則是提供可聚焦 (或組合) 的一系列細微功能,而非數個單體式元件。這個方法有許多優點。
控制
層級元件越高,您就越能執行更多操作,但會限制您能夠擁有的直接控制權。如果您需要進一步控管,可以「放置」到較低層級的元件。
舉例來說,如要讓元件的顏色能夠建立動畫,您可以使用 animateColorAsState
API:
val color = animateColorAsState(if (condition) Color.Green else Color.Red)
不過,如果您需要該元件一律顯示為灰色,便無法使用這個 API 執行。您可以改為使用較低層級的 Animatable
API:
val color = remember { Animatable(Color.Gray) } LaunchedEffect(condition) { color.animateTo(if (condition) Color.Green else Color.Red) }
較高層級的 animateColorAsState
API 本身是在較低層級的 Animatable
API 上建構。使用較低層級 API 較為複雜,但可控制更多設定。請選擇最符合需求的抽象層級。
自訂
從較小的建構區塊組成層級較高的元件,就能更輕鬆地自訂所需的元件。舉例來說,假設 Material 層提供了 Button
的 實作:
@Composable fun Button( // … content: @Composable RowScope.() -> Unit ) { Surface(/* … */) { CompositionLocalProvider(/* … */) { // set LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { Row( // … content = content ) } } } }
Button
是由 4 個元件組合而成:
提供背景、形狀、點擊處理等作業的
Surface
資料。CompositionLocalProvider
會在啟用或停用按鈕時變更內容的 Alpha 值ProvideTextStyle
可設定要使用的預設文字樣式Row
會提供按鈕內容的預設版面配置政策
我們省略了部分參數和註解,以更清楚地顯示結構,不過整個元件只約 40 行程式碼,只是要組合這些 4 個元件來實作按鈕。像 Button
這類元件則會注意自己所公開的參數,讓可以廣泛使用的自訂參數相輔相成,讓元件更容易使用。舉例來說,材料元件提供質感設計系統中指定的自訂項目,讓您輕鬆遵循質感設計原則。
不過,如果您想要自訂元件參數以外的自訂項目,則可以「捨棄」層級並建立元件分支。舉例來說,質感設計會指定按鈕應使用純色背景。如果您需要漸層背景,Button
參數不支援這個選項。在這種情況下,您可以使用 Material Button
實作做為參考資料,並建構自己的元件:
@Composable fun GradientButton( // … background: List<Color>, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background( Brush.horizontalGradient(background) ) ) { CompositionLocalProvider(/* … */) { // set material LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { content() } } } }
上述實作仍繼續使用 Material 層的元件,例如 Material 的目前內容 Alpha 版概念和目前文字樣式。但用來取代素材 Surface
和 Row
,並設定樣式,呈現理想的外觀。
如果您完全不想使用 Material 概念,例如自行建構專屬設計系統,則可選擇使用基礎層元件:
@Composable fun BespokeButton( // … backgroundColor: Color, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background(backgroundColor) ) { // No Material components used content() } }
Jetpack Compose 會保留最高階元件的最簡單名稱。舉例來說,androidx.compose.material.Text
是以 androidx.compose.foundation.text.BasicText
為基礎。如此一來,如果想取代較高層級,則可透過自己的可偵測名稱提供自己的實作項目。
挑選合適的抽象層
不過,Compose 建構了可重複使用的可重複使用元件的理念,因此,您未必會觸及較低等級的建構模塊。許多更高層級的元件不僅提供更多功能,而且通常會實作無障礙設計等最佳做法。
舉例來說,如果想要新增自訂元件的手勢支援,您可以使用 Modifier.pointerInput
從頭開始建立,但還有其他更高階的元件以這種方式為基礎,或許還能提供更好的起點,例如 Modifier.draggable
、Modifier.scrollable
。或 Modifier.swipeable
。
建議您以「最高層級」元件做為建構依據,以提供所需的功能,以享有其中包含的最佳做法。
瞭解詳情
如需建構自訂設計系統的範例,請參閱 Jetsnack 範例。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 適用於 Jetpack Compose 的 Kotlin
- 清單和格線
- Compose 中的連帶效果