ANDROIDX / COMPOSE / MATERIAL 3
MaterialExpressiveTheme
看清 Expressive 主题默认注入的颜色、运动、形状与排版,以及嵌套主题的行为。
它真正做了什么
首次进入 MaterialExpressiveTheme 时,源码把未传入的参数替换为以下默认值:
MaterialTheme(
colorScheme = colorScheme ?: expressiveLightColorScheme(),
motionScheme = motionScheme ?: MotionScheme.expressive(),
shapes = shapes ?: Shapes(),
typography = typography ?: Typography(),
content = content,
)所以 M3E 的主题入口不是只换颜色,它同时建立了 color、motion、shape、typography 四类默认值。
深色模式不是自动的
expressiveLightColorScheme() 的 KDoc 明确说它是 light scheme,并建议暗色模式使用 darkColorScheme()。官方 sample 也是自行判断系统主题:
val colorScheme =
if (isSystemInDarkTheme()) darkColorScheme()
else expressiveLightColorScheme()
MaterialExpressiveTheme(colorScheme = colorScheme) {
AppContent()
}也就是说,直接空参数调用 MaterialExpressiveTheme 时,源码默认落到 expressive 浅色配色;暗色切换仍由应用负责。
嵌套时为什么不重置
实现内部用 LocalUsingExpressiveTheme 判断是否已经处于 Expressive 主题。嵌套调用时,未提供的值继承当前 MaterialTheme,不会重新套一遍默认浅色主题。
推荐的应用主题壳
@Composable
fun ZMTheme(content: @Composable () -> Unit) {
val colors =
if (isSystemInDarkTheme()) darkColorScheme()
else expressiveLightColorScheme()
MaterialExpressiveTheme(
colorScheme = colors,
content = content,
)
}这只是源码可支持的最小写法。动态取色、品牌色、状态栏和可访问性对比度仍应按项目需求补充。
源码依据
- 实现:
MaterialTheme.kt:261-287 - 官方示例:
ThemeSamples.kt:94-125 - 浅色 scheme 说明:
ColorScheme.kt:1157-1173