Skip to content

构建设计系统 (Design System)

源:Compose 中的 Material Design

在大型项目中,直接使用 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(...)
}