构建设计系统 (Design System)
在大型项目中,直接使用 MaterialTheme 往往不够,因为设计师可能会定义 Material 规范之外的颜色(如 success, warning, brand)或特定排版。
我们需要构建一个语义化的设计系统。
1. 定义扩展颜色
Material 3 的 ColorScheme 有固定的槽位(Primary, Secondary...)。如果不够用,不要硬编码颜色值,而是扩展它。
kotlin
@Immutable
data class ExtendedColors(
val success: Color,
val warning: Color,
val onSuccess: Color
)
val LocalExtendedColors = staticCompositionLocalOf {
ExtendedColors(Color.Unspecified, Color.Unspecified, Color.Unspecified)
}2. 封装 Theme
创建一个自定义的 AppTheme,将 Material Theme 和扩展颜色组合起来。
kotlin
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = if (darkTheme) DarkColors else LightColors
val extendedColors = if (darkTheme) DarkExtendedColors else LightExtendedColors
CompositionLocalProvider(LocalExtendedColors provides extendedColors) {
MaterialTheme(
colorScheme = colorScheme,
typography = AppTypography,
shapes = AppShapes,
content = content
)
}
}
// 便捷访问对象
object AppTheme {
val colors: ColorScheme
@Composable
get() = MaterialTheme.colorScheme
val extendedColors: ExtendedColors
@Composable
get() = LocalExtendedColors.current
}3. 使用
kotlin
// 现在的代码非常语义化
Text(
text = "Success!",
color = AppTheme.extendedColors.success
)4. 封装组件 (Atomic Design)
不要直接在业务代码中使用 Button。应该封装基础组件 AppButton,锁定样式。
kotlin
@Composable
fun AppButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
// 限制只能使用设计规范中的大小
size: AppButtonSize = AppButtonSize.Medium,
content: @Composable RowScope.() -> Unit
) {
// 统一处理高度、圆角、字体
Button(...)
}