Skip to content

主题 — HuaLuoTheme ​

颜色、字阶、形状、动效的唯一来源。在应用入口调用一次,整个界面树包在它里面即可。

基本用法 ​

kotlin
HuaLuoTheme(darkTheme = isSystemInDarkTheme()) {
    App()
}

跟随设置里的深浅色选项(0 跟随系统 / 1 强制浅 / 2 强制深):

kotlin
val option by settings.darkModeOption.collectAsState()
HuaLuoTheme(darkTheme = resolveDarkTheme(option)) {
    App()
}

整份换配色:

kotlin
HuaLuoTheme(darkTheme = dark, colorScheme = myColorScheme) {
    App()
}

取弹簧动效规格:

kotlin
val spec = MaterialTheme.motionScheme.defaultSpatialSpec<Float>()
animateFloatAsState(targetValue = x, animationSpec = spec)

参数 ​

HuaLuoTheme ​

参数类型默认值说明
darkThemeBoolean—必传,没有默认值。 决定配色,也决定状态栏 / 导航栏图标的明暗
colorSchemeColorSchemedefaultColorScheme(darkTheme)配色入口。整份传进来即可换肤
content@Composable () -> Unit—界面树

它内部已经帮你装好的东西(不要再自己加):MaterialExpressiveTheme(含 MotionScheme.expressive())、Shapes、Typography、LocalOverscrollFactory(过度滚动)、以及轻提示的渲染容器 PopupPrompt()。

defaultColorScheme ​

参数类型说明
darkThemeBoolean返回 DefaultDarkScheme 或 DefaultLightScheme

resolveDarkTheme ​

参数类型说明
darkModeOptionInt1 → false(浅色)、2 → true(深色)、其它 → isSystemInDarkTheme()

三个可以直接引用的对象 ​

名称说明
DefaultLightScheme / DefaultDarkScheme两套内置 ColorScheme,顶层 val
Shapes形状系统,见形状
Typography字阶,见字阶

要点 ​

  • darkTheme 必传。 它没有默认值 —— 显式写出来,别指望它自己跟系统。
  • colorScheme 和 darkTheme 是两件事:colorScheme 管颜色,darkTheme 管状态栏 / 导航栏图标的明暗。整份换配色时两个都要传对,否则会出现「浅色配色配浅色系统图标」这种读不清的组合。
  • 颜色没有第二个入口。 统一走 MaterialTheme.colorScheme.xxx,M3 那 45 个槽位就是全部约定 —— 别在组件之外硬编码 Color(0xFF...)。
  • Color.kt 里那两套 token(*Light / *Dark)是给主题构造用的,业务代码不该直接引用 —— 换肤时它们不跟着走。
  • 动效不要写死时长。 用 MaterialTheme.motionScheme 里的规格(defaultSpatialSpec / defaultEffectsSpec),写死 tween(300) 就换不回来了。
  • 只调一次。 嵌套第二层 HuaLuoTheme 会把过度滚动工厂和轻提示容器也再挂一份,而且内层会整体覆盖外层配色。

说明 ​

  • 根节点是 MaterialExpressiveTheme,不是普通 MaterialTheme。 它会把 motion scheme 默认设为 MotionScheme.expressive(),并把 Expressive 的形状 / 字阶 / 色板接进来。Expressive 组件(ButtonGroup、SplitButton、FloatingActionButtonMenu、波浪 LoadingIndicator 等)只有挂在这个主题下才会拿到 expressive 的动效与形状默认值;挂在普通 MaterialTheme 下会退回标准 M3 观感,Expressive 组件会「名不副实」。
  • 配色只有 ColorScheme 一个入口。 需要什么语义就挑对应的 M3 槽位;M3 规范里没有的状态色(成功绿、警告琥珀这类)由用到它的组件自己写常量,不再往主题里塞第二套「扩展配色」—— 那套东西每加一个语义色就要多维护一组明暗映射,还把「换配色」从改一个文件变成改两个。
  • Color.kt 只存纯配色 token(Material Theme Builder 的标准产物:明 / 暗各一套,外加 medium / high contrast 变体),它不构造任何 ColorScheme —— 把 token 装成 ColorScheme 的活全在 Theme.kt 里。这样换配色只要替换 Color.kt,一行代码都不用动;以后要加对比度档位、动态取色、节日主题,只改 Theme.kt,不碰配色文件。
  • 两套 ColorScheme 是顶层 val,不是每次调用重建。 ColorScheme 是不可变对象,45 个槽位全量构造一次就够。放进 HuaLuoTheme 里每次重组 new 一份不仅浪费,还会让下游所有 remember(colorScheme) / derivedStateOf 缓存全部失效。
  • 深色模式由调用方传入,主题不去读任何设置仓库。 原因:这个库是独立发布的 AAR,被多个 APK 使用,各边的设置类不同名 —— 库里去 bind 任意一边都会让另一边编译不过。
  • 状态栏 / 导航栏图标的明暗是在 SideEffect 里设的(isAppearanceLightStatusBars / isAppearanceLightNavigationBars = !darkTheme),预览模式下跳过。
  • defaultColorScheme 的 when 是预留的扩展点:以后要插第三套配色就在那里加分支 —— Color.kt 已经备好了 medium / high contrast 两组 token,照抄现有构造块的写法、把 token 名换成带 MediumContrast / HighContrast 后缀的那组即可。