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
,请参阅“使用 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 = ""
)
}
/* ... */
Theme 函数
Theme 函数是入口点和主 API。该函数会构造主题系统 CompositionLocalProvider
的实例(使用任何逻辑所需的实际值),这些实例会通过 CompositionLocal
提供给组合树。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
)
}
Theme 对象
通过具有便捷属性的对象访问主题系统。为了保持一致性,对象往往采用与 Theme 函数相同的名称。这些属性只会获取当前的 CompositionLocal。
// 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
/* ... */
}