Jetpack Compose 的主題是由多個較低層級的建構和相關 API 組成。您可以在 MaterialTheme
的原始碼中查看這些套件,也可在自訂設計系統中套用。
主題系統類別
主題通常由許多系統組成,而這些系統會將常見的視覺和行為概念分組。這些系統可以使用具有主題值的類別建模。
舉例來說,MaterialTheme
包含 Colors
(色彩系統)、Typography
(字型系統),以及 Shapes
(形狀系統)。
@Immutable
data class ColorSystem(
val color: Color,
val gradient: List<Color>
/* ... */
)
@Immutable
data class TypographySystem(
val fontFamily: FontFamily,
val textStyle: TextStyle
)
/* ... */
@Immutable
data class CustomSystem(
val value1: Int,
val value2: String
/* ... */
)
/* ... */
主題系統組合本機值
主題系統類別會以隱含形式提供給組合樹,做為 CompositionLocal
執行個體。這可讓可組合函式中的主題值採用靜態參照。
如要進一步瞭解 CompositionLocal
,請參閱 使用 CompositionLocal 的本機範圍資料指南。
val LocalColorSystem = staticCompositionLocalOf {
ColorSystem(
color = Color.Unspecified,
gradient = emptyList()
)
}
val LocalTypographySystem = staticCompositionLocalOf {
TypographySystem(
fontFamily = FontFamily.Default,
textStyle = TextStyle.Default
)
}
val LocalCustomSystem = staticCompositionLocalOf {
CustomSystem(
value1 = 0,
value2 = ""
)
}
/* ... */
主題功能
主題函式為進入點和主要 API,可建構主題系統 CompositionLocal
的執行個體 (使用任何邏輯的必要實際值),提供給具有 CompositionLocalProvider
的組合樹。content
參數允許巢狀的可組合值存取階層相對的主題值。
@Composable
fun Theme(
/* ... */
content: @Composable () -> Unit
) {
val colorSystem = ColorSystem(
color = Color(0xFF3DDC84),
gradient = listOf(Color.White, Color(0xFFD7EFFF))
)
val typographySystem = TypographySystem(
fontFamily = FontFamily.Monospace,
textStyle = TextStyle(fontSize = 18.sp)
)
val customSystem = CustomSystem(
value1 = 1000,
value2 = "Custom system"
)
/* ... */
CompositionLocalProvider(
LocalColorSystem provides colorSystem,
LocalTypographySystem provides typographySystem,
LocalCustomSystem provides customSystem,
/* ... */
content = content
)
}
主題物件
若要存取主題系統,可以使用具有便利屬性的物件。為保持一致性,物件通常會採用與主題函式相同的名稱。屬性只會取得本機目前的組合。
// Use with eg. Theme.colorSystem.color
object Theme {
val colorSystem: ColorSystem
@Composable
get() = LocalColorSystem.current
val typographySystem: TypographySystem
@Composable
get() = LocalTypographySystem.current
val customSystem: CustomSystem
@Composable
get() = LocalCustomSystem.current
/* ... */
}