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)

具体代码路径

相关推荐
小和尚敲代码4 天前
初识php库管理工具composer的体验【爽】使用phpword模板功能替换里面的字符串文本
开发语言·php·composer
十一侍卫14 天前
composer使用
android·android studio·composer
清冬暖雪1 个月前
在Fiddler中的Composer使用post方法发送非法数据
前端·fiddler·composer
那天的烟花雨1 个月前
android display 笔记(五)HWC(Hardware Composer)
android·笔记·composer
xianyinsuifeng2 个月前
AWS无服务器 应用程序开发—第十七章 Application Composer
serverless·aws·composer
fonx2 个月前
如何设置PHP wkhtmltopdf
开发语言·php·composer
liuxin334455662 个月前
深入掌握Symfony与Composer:PHP依赖管理的艺术
php·composer·symfony
一分半心动3 个月前
composer 安装如何彻底删除
android·php·composer
007php0073 个月前
PHP调用阿里云OSS的SDK封装成服务的完整指南与问题解决
java·开发语言·经验分享·笔记·git·功能测试·gpt·其他·nginx·百度·阿里云·docker·微信·chatgpt·架构·golang·系统架构·单元测试·appium·云计算·json·github·aigc·php·企业微信·文心一言·sass·课程设计·ai编程·laravel·微信公众平台·phpstorm·可用性测试·facebook·oneapi·twitter·composer·paddle·新浪微博·segmentfault·微信开放平台
007php0073 个月前
如何生成自定义二维码和实现安全便捷的扫码登录功能以及对接企业微信API
java·开发语言·经验分享·redis·笔记·git·功能测试·jmeter·其他·nginx·安全·百度·ajax·ci/cd·docker·微信·架构·golang·系统架构·单元测试·centos·github·jenkins·php·erlang·企业微信·postman·sass·课程设计·微信公众平台·safari·facebook·oneapi·twitter·composer·jira·paddle·新浪微博·lvs·segmentfault·微信开放平台