# 主题light和dark

iOS 13+Android 10+ 提供了暗黑模式/深色模式,之前的模式称为light,暗黑称为dark。

同时也要注意,低于上述版本的手机,系统层没有暗黑模式概念。

在uni-app x中,有3种主题概念:OSTheme、hostTheme、appTheme。每种主题在不同平台支持度不同,获取、设置和监听变化的方式也不同。

主题概念 描述 App Web 小程序 获取方式 设置方式 监听变化
osTheme 手机OS的当前主题 x x uni.getDeviceInfo - uni.onOsThemeChange
hostTheme 浏览器或小程序宿主的当前主题 x uni.getDeviceInfo - uni.onHostThemeChange
appTheme App当前主题 X x uni.getAppBaseInfo uni.setAppTheme uni.onAppThemeChange

Web和小程序注意:

  1. 没有能力获取os的主题。只能获取浏览器或小程序宿主的主题,即hostTheme。
  2. 可以选择不响应hostTheme,也可以根据hostTheme调整自身的表现。
  3. 某些浏览器或小程序自带API会涉及UI,其主题是跟随hostTheme来的,开发者的应用无法控制这些ui的主题。比如浏览器的alert()、小程序的showModal。

应用适配暗黑主题,可以选择:

  1. 跟随上家,比如app平台跟随OSTheme,web和小程序跟随hostTheme。
  2. 不跟随上家,应用自己独立设置主题。比如有的应用只有暗黑模式,有的应用给用户提供了主题选择列表,允许用户选择和osTheme不一样的主题。

一般情况下,独立设置主题的场景常见于App平台,所以App平台新增了appTheme的概念。appTheme有几个用途:

  1. 独立于osTheme设置主题
  2. 方便开发者和插件作者协作。推荐各个插件作者在涉及UI时,支持主题适配,响应App的主题变化
  3. uni-app x框架自带的一些UI页面,比如showActionSheet、比如pages.json的页面设置,会响应appTheme的变化

开发者做主题适配时需考虑的内容范围:

  1. 开发者自己的uvue代码 大部分主题通过css设置,web和小程序平台可以使用媒体查询来设置。有部分ui需要通过组件的属性或内置API的参数来设置。
  2. pages.json的页面设置,推荐通过theme.json设置
  3. uni-app x的App和Web平台框架中自带的界面(小程序平台由小程序宿主自行适配,与uni-app x框架无关)
    • uni.showActionSheet (从HBuilderX 4.51起适配暗黑模式)
    • uni.showModal (暂未适配暗黑模式)
    • uni.chooseLocation (从HBuilderX 4.33起适配暗黑模式)
    • uni.openLocation (从HBuilderX 4.41起适配暗黑模式)
    • uni.chooseImage/chooseVideo/chooseMedia/chooseFile,当调用系统的选择界面时,该界面的主题跟随osTheme,应用层无法干预

注意:有些平台,os主题变化时会重启App,有些小程序宿主主题变化时会重启小程序,有些则不会。在会重启的场景下,监听主题变化其实没有意义。

# uni.setAppTheme(options)

设置应用主题

uni.setAppTheme,并不会帮助开发者自动实现整个应用的亮/暗主题切换,它的作用是:

  1. 根据theme.json,设置pages.json的亮/暗主题
  2. 触发uni.onAppThemeChange,开发者和组件作者均可监听这个事件,自行响应将页面设置为对应的亮/暗风格。

当然组件作者也可以不监听onAppThemeChange,而是暴露主题切换API给开发者,由开发者监听主题切换,再调用组件的主题切换API。

目前uni-app x的内置组件和UI相关的API(比如showModal),并不会响应setAppTheme。组件是暴露了样式属性供开发者自行设置,Modal相关API目前没有样式设置,后续会升级支持。

# setAppTheme 兼容性

Web 微信小程序 Android Android uni-app x UTS 插件 iOS iOS uni-app x UTS 插件
x x 4.18 4.18 4.18 4.18

# 参数

名称 类型 必填 默认值 兼容性 描述
options SetAppThemeOptions -
名称 类型 必备 默认值 兼容性 描述
theme string -
主题
合法值 兼容性 描述
light - -
dark - -
auto - -
success (result: SetAppThemeSuccessResult) => void null
接口调用成功的回调函数
fail (result: IAppThemeFail) => void null
接口调用失败的回调函数
complete (result: any) => void null
接口调用结束的回调函数(调用成功、失败都会执行)

# SetAppThemeSuccessResult 的属性值

名称 类型 必备 默认值 兼容性 描述
theme string - - -

# IAppThemeFail 的属性值

名称 类型 必备 默认值 兼容性 描述
errCode number -
错误码
- 702001 参数错误
- 2002000 未知错误
合法值 兼容性 描述
702001 - -
2002000 - -
errSubject string - - 统一错误主题(模块)名称
data any - - 错误信息中包含的数据
cause Error - - 源错误信息,可以包含多个错误,详见SourceError
errMsg string - - -
uni.setAppTheme({
  theme: "auto",
  success: function() {
    console.log("设置appTheme为 auto 成功")
  },
  fail: function(e: IAppThemeFail) {
    console.log("设置appTheme为 auto 失败,原因:", e.errMsg)
  }
})

# 参见

# uni.onAppThemeChange(callback)

开启监听应用主题变化

版本历史调整

  • HBuilderX 4.18版本的逻辑是:uni.setAppTheme 设置的 theme 值变化时触发本监听回调,回调参数中的 appTheme 值可能是"light" | "dark" | "auto"。在 app 平台设置应用的 theme 值为 auto 后,需再次查询osTheme来判断当前的真实主题。如果应用主题是auto,那么需要同时监听osTheme的变化。
  • HBuilderX 4.19版本调整为:应用的light/dark主题真正发生变化时触发监听回调。无论是手动设置setAppTheme还是跟随osTheme变化,只要真正变化了就会触发本监听。回调参数中的 appTheme 值只能是"light" | "dark"。

# onAppThemeChange 兼容性

Web 微信小程序 Android Android uni-app x UTS 插件 iOS iOS uni-app x UTS 插件
x x 4.18 4.18 4.18 4.18

# 参数

名称 类型 必填 默认值 兼容性 描述
callback (res: AppThemeChangeResult) => void - - -

# AppThemeChangeResult 的属性值

名称 类型 必备 默认值 兼容性 描述
appTheme string -
应用主题

# 返回值

类型
number
//callbackId 用于注销监听
val callbackId = uni.onAppThemeChange((res: AppThemeChangeResult) => {
  console.log("onAppThemeChange", res.appTheme)
})

# 参见

# uni.offAppThemeChange(id)

取消监听应用主题变化

# offAppThemeChange 兼容性

Web 微信小程序 Android Android uni-app x UTS 插件 iOS iOS uni-app x UTS 插件
x - 4.18 4.18 4.18 4.18

# 参数

名称 类型 必填 默认值 兼容性 描述
id number - - -
val callbackId = uni.onAppThemeChange((res: AppThemeChangeResult) => {
  console.log("onAppThemeChange", res.appTheme)
})
//...
//...
//注销监听
uni.offAppThemeChange(this.appThemeChangeId)

# 参见

# uni.onOsThemeChange(callback)

开启监听系统主题变化

# onOsThemeChange 兼容性

Web 微信小程序 Android Android uni-app x UTS 插件 iOS iOS uni-app x UTS 插件
x x 4.18 4.18 4.18 4.18

# 参数

名称 类型 必填 默认值 兼容性 描述
callback (res: OsThemeChangeResult) => void - - -

# OsThemeChangeResult 的属性值

名称 类型 必备 默认值 兼容性 描述
osTheme string -
系统主题

# 返回值

类型
number
//callbackId 用于注销监听
val callbackId = uni.onOsThemeChange((res: OsThemeChangeResult)=> {
    console.log("onOsThemeChange---", res.osTheme)
})

# 参见

注意:

  • android 10、iOS 13 才开始支持深色模式主题 dark,更低版本无法获取、监听OS的主题。

# uni.offOsThemeChange(id)

取消监听系统主题变化

# offOsThemeChange 兼容性

Web 微信小程序 Android Android uni-app x UTS 插件 iOS iOS uni-app x UTS 插件
x x 4.18 4.18 4.18 4.18

# 参数

名称 类型 必填 默认值 兼容性 描述
id number - - -
val callbackId = uni.onOsThemeChange((res: OsThemeChangeResult)=> {
    console.log("onOsThemeChange---", res.osTheme)
})
...
...
//注销监听
uni.offOsThemeChange(callbackId)

# 参见

# uni.onHostThemeChange(callback)

监听宿主题状态变化。

# onHostThemeChange 兼容性

Web 微信小程序 Android iOS
4.35 4.41 x x

# 参数

名称 类型 必填 默认值 兼容性 描述
callback (result: OnHostThemeChangeCallbackResult) => void - - -

# OnHostThemeChangeCallbackResult 的属性值

名称 类型 必备 默认值 兼容性 描述
hostTheme string - - 主题名称
合法值 兼容性 描述
dark - -
light - -

# 返回值

类型
number

# 参见

# uni.offHostThemeChange(id)

取消监听宿主题状态变化。

# offHostThemeChange 兼容性

Web 微信小程序 Android iOS
4.35 4.41 x x

# 参数

名称 类型 必填 默认值 兼容性 描述
id number - - -

# 参见

# uni.onThemeChange(callback)

监听系统主题状态变化。 已废弃,在web、小程序上推荐使用 onHostThemeChange

# onThemeChange 兼容性

Web 微信小程序 Android iOS
4.0 4.41 x x

# 参数

名称 类型 必填 默认值 兼容性 描述
callback (result: OnThemeChangeCallbackResult) => void - - -

# OnThemeChangeCallbackResult 的属性值

名称 类型 必备 默认值 兼容性 描述
theme string -
主题名称
合法值 兼容性 描述
dark - -
light - -

# 参见

# uni.offThemeChange(callback)

取消监听系统主题状态变化。 已废弃,在web、小程序上推荐使用 offHostThemeChange

# offThemeChange 兼容性

Web 微信小程序 Android iOS
4.0 4.41 x x

# 参数

名称 类型 必填 默认值 兼容性 描述
callback (result: OnThemeChangeCallbackResult) => void - - -

# OnThemeChangeCallbackResult 的属性值

名称 类型 必备 默认值 兼容性 描述
theme string -
主题名称
合法值 兼容性 描述
dark - -
light - -

# 参见

# 通用类型

# GeneralCallbackResult

名称 类型 必备 默认值 兼容性 描述
errMsg string -
错误信息