Compose之主题

Compose官方推荐使用Surface来给任何可组合项设置颜色,Surface的color属性就默认设置了 MaterialTheme.colors.surface色值。

scss 复制代码
Row(Modifier.background(MaterialTheme.colors.primary))     // 不推荐

Surface(color = MaterialTheme.colors.primary) {    // 推荐
    Row(
    ...
    )
}

Surface(
  color: Color = MaterialTheme.colors.surface,
  contentColor: Color = contentColorFor(color),
  ...
)

TopAppBar(
  backgroundColor: Color = MaterialTheme.colors.primarySurface,
  contentColor: Color = contentColorFor(backgroundColor),
  ...
)

实现暗色主题,可以使用Preview的uiMode=UI_MODE_NIGHT_YES,还可以使用TestTheme(darkTheme = true),前提是内容要使用Surface。

kotlin 复制代码
@Composable
private fun Greetings() {
    Surface {
        Text(text = "July 2021")
        Icon(imageVector = Icons.Filled.AccountBox, contentDescription = null)
    }
}

@Preview(
    widthDp = 320,
    uiMode = UI_MODE_NIGHT_YES,
    name = "Dark"
)
@Preview(widthDp = 320)
@Composable
fun GreetingsPreview() {
    TestTheme {
        Greetings()
    }
}

@Preview(widthDp = 320)
@Composable
fun GreetingsPreviewAnother() {
    TestTheme(darkTheme = false) {
        Greetings()
    }
}

Surface的细节如下:

kotlin 复制代码
fun Surface(
    modifier: Modifier = Modifier,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),
    ...
)
fun contentColorFor(backgroundColor: Color) =
    MaterialTheme.colorScheme.contentColorFor(backgroundColor).takeOrElse {
        LocalContentColor.current
    }
// color若为primary的颜色值,则contentColor为 onPrimary的颜色值,二者一一对应
fun ColorScheme.contentColorFor(backgroundColor: Color): Color =
    when (backgroundColor) {
        primary -> onPrimary
        secondary -> onSecondary
        tertiary -> onTertiary
        background -> onBackground
        error -> onError
        surface -> onSurface
        surfaceVariant -> onSurfaceVariant
        primaryContainer -> onPrimaryContainer
        secondaryContainer -> onSecondaryContainer
        tertiaryContainer -> onTertiaryContainer
        errorContainer -> onErrorContainer
        inverseSurface -> inverseOnSurface
        else -> Color.Unspecified
    }

Surface 的color 默认值是MaterialTheme.colorScheme.surface,contentColor的color 默认值是MaterialTheme.colorScheme.onSurface

项目的theme文件中LightColorScheme/DarkColorScheme会给MaterialTheme的colorScheme重新赋值,若LightColorScheme/DarkColorScheme未定义surface和onSurface,则使用系统默认的颜色。

以darkColorScheme为例

ini 复制代码
fun darkColorScheme(
    primary: Color = ColorDarkTokens.Primary,
    onPrimary: Color = ColorDarkTokens.OnPrimary,
    ...
    secondary: Color = ColorDarkTokens.Secondary,
    onSecondary: Color = ColorDarkTokens.OnSecondary,
    ...
background: Color = ColorDarkTokens.Background,
    onBackground: Color = ColorDarkTokens.OnBackground,
    surface: Color = ColorDarkTokens.Surface,
    onSurface: Color = ColorDarkTokens.OnSurface,
    ...
): ColorScheme =
    ColorScheme(
        primary = primary,
        onPrimary = onPrimary,
        ...
        secondary = secondary,
        onSecondary = onSecondary,
        ...
        background = background,
        onBackground = onBackground,
        surface = surface, //Color(red = 28, green = 27, blue = 31)
        onSurface = onSurface, // Color(red = 230, green = 225, blue = 229)
        ...
    )

故TestTheme(darkTheme = true)或uiMode = UI_MODE_NIGHT_YES时,color即整个平面为黑色,contentColor即text/icon为白色。反之同理。

若theme中定义

ini 复制代码
private val DarkColorScheme = darkColorScheme(
    surface = Color.Green,
    onSurface = Color.Red,
}
private val LightColorScheme = lightColorScheme(
    surface = Color.Yellow,
    onSurface = Color.Gray,
}

则效果为:

若theme中定义

ini 复制代码
private val DarkColorScheme = darkColorScheme(
    primary = Color.Red,
    onPrimary = Color.Green
)

private val LightColorScheme = lightColorScheme(
    primary = Color.Gray,
    onPrimary = Color.Yellow
)

修改Surface的color为MaterialTheme.colorScheme.primary ,则contentColor默认找MaterialTheme.colorScheme.onPrimary 如:

ini 复制代码
Surface(color = MaterialTheme.colorScheme.primary)

效果如下

参考:

使用 Material 3 在 Compose 中设置主题 | Android Developers (google.cn)

初识 MaterialTheme | 你好 Compose (jetpackcompose.cn)

Surface | 你好 Compose (jetpackcompose.cn)

Jetpack-Compose 学习笔记(六)------ Compose 主题 Theme 一探究竟,换肤还能如此 Easy?-腾讯云开发者社区-腾讯云 (tencent.com)

具体代码路径

相关推荐
Carson带你学Android9 天前
Compose 终于上线 FlexBox:换行与弹性伸缩 都轻松搞定!
android·composer
qq75903536610 天前
2026 docker run启动的容器通过命令导出为docker-composer.yml文件
docker·eureka·composer
故渊at10 天前
第十四板块:Android 硬件抽象与安全加固 | 第三十四篇:Hardware Composer (HWC) 与 显示安全(HDCP)
android·安全·composer·安全加固·hwc·硬件抽象
右耳朵猫AI11 天前
PHP周刊2026W23 | Composer 2.10、Symfony 8.1、Twig 3.27.1、PHP 8.5、Laravel AI SDK
php·composer·symfony
buyue__13 天前
Composer——PHP 依赖管理器
composer
chushiyunen20 天前
php包管理工具composer笔记
笔记·php·composer
CaliXz21 天前
iOS图标边缘效果问题及解决方法
php·composer
猫头虎21 天前
Cursor推出的Composer 2.5 是什么?从定向 RL 到合成数据,AI 编程智能体再进化
人工智能·开源·prompt·aigc·copilot·ai编程·composer
bill328227804323 天前
AE 的 Animation Composer 描边动效玩法 + 极简 MG 制作流程(含示例)
php·composer
薛定猫AI1 个月前
【深度解析】Composer 2.5 编程模型:速度智能比、Agent 工作流与 AI 编码实战评估
人工智能·php·composer