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)

具体代码路径

相关推荐
IAM四十二2 天前
Jetpack Compose State 你用对了吗?
android·android jetpack·composer
yanwushu6 天前
Xserver v1.4.2发布,支持自动重载 nginx 配置
mysql·nginx·php·个人开发·composer
芝麻酱堂1 个月前
CentOS7.9 安装 Composer
php·composer
DreamCoders1 个月前
Composer 设置 阿里云 全量镜像
阿里云·php·laravel·composer
微刻时光1 个月前
Linux编译部署PHP环境
linux·开发语言·redis·git·php·apache·composer
pikazo1 个月前
composer详解
android·php·composer
王大爷~2 个月前
composer环境变量(phpstudy集成环境)无法使用问题
php·composer
小和尚敲代码2 个月前
初识php库管理工具composer的体验【爽】使用phpword模板功能替换里面的字符串文本
开发语言·php·composer
十一侍卫2 个月前
composer使用
android·android studio·composer
清冬暖雪3 个月前
在Fiddler中的Composer使用post方法发送非法数据
前端·fiddler·composer