# DarkMode 适配指南 @darkmode > HBuilder X 3.6.9+ 支持 暗黑模式(Dark Mode),也被称为夜间模式或深色模式,是一种高对比度,或者反色模式的显示模式。是一种有利于在黑暗环境下观看手机的高对比度的模式。uni-app的暗黑模式,是帮助开发者完成自己应用的暗黑模式的一批配置和API。开发者可以参考本文实现自己应用的暗黑模式。 > 插件市场示例项目:[https://ext.dcloud.net.cn/plugin?name=hello-darkmode](https://ext.dcloud.net.cn/plugin?name=hello-darkmode) ## 开启 DarkMode @open-darkmode > 在 `manifest.json` 配置,应用的部分配置可通过变量的形式配置,在变量配置文件中定义不同主题下的颜色或图标,各平台配置如下: ### app-plus 在 `manifest.json -> app-plus` 中配置: 1. 配置 `darkmode:true` 2. 配置 `themeLocation`,指定变量配置文件 `theme.json` 路径,例如:在根目录下新增 `theme.json`,需要配置 `"themeLocation":"theme.json"` 3. 在 `theme.json` 中定义相关变量 4. 在 `pages.json` 中以@开头引用变量 5. 整体配置 ```json "app-plus" : { "darkmode" : true, "themeLocation" : "theme.json" // 如果 theme.json 在根目录可省略 } ``` #### iOS 安全区域适配 - 开启安全区域占位 > 在 manifest.json 文件的 "app-plus" 节点下添加 "safearea" 适配 iOS 的安全区域,"background" 对应正常模式下安全区域外的背景颜色,"backgroundDark"对应暗黑模式下安全区域外的背景颜色 ```json "app-plus" : { "safearea": { //iOS平台的安全区域 "background": "#ffffff", "backgroundDark": "#2f0508", // HX 3.1.19+支持 "bottom": { "offset": "auto" } } } ``` - 关闭安全区域占位 > 将 "offset" 置为 “none” 关闭安全区域的占位,注:关闭安全区域占位在刘海屏页面内容可能会被 “homeBar” 挡住,需要自行适配,具体请参考文档 [iOS 刘海屏适配](https://ask.dcloud.net.cn/article/35564) ```json "safearea": { "bottom": { "offset": "none" } } ``` **注意:** - `iOS 13+`、`Android 10+`设备上才支持 - 需要云端打包生效 ### h5 在 `manifest.json -> h5` 中配置: 1. 配置 `darkmode:true` 2. 配置 `themeLocation`,指定变量配置文件 `theme.json` 路径,例如:在根目录下新增 `theme.json`,需要配置 `"themeLocation":"theme.json"` 3. 在 `theme.json` 中定义相关变量 4. 在 `pages.json` 中以@开头引用变量 5. 整体配置 ```json "h5" : { "darkmode" : true, "themeLocation" : "theme.json" // 如果 theme.json 在根目录可省略 } ``` ### mp-weixin 在 `manifest.json -> mp-weixin` 中配置: 1. 配置 `darkmode:true` 2. 配置 `themeLocation`,指定变量配置文件 `theme.json` 路径,例如:在根目录下新增 `theme.json`,需要配置 `"themeLocation":"theme.json"` 3. 在 `theme.json` 中定义相关变量 4. 在 `pages.json` 中以@开头引用变量 5. 整体配置 ```json "mp-weixin" : { "darkmode" : true, "themeLocation" : "theme.json" // 如果 theme.json 在根目录可省略 } ``` 支持通过变量配置的属性如下所示: - 全局配置 globalStyle 与页面支持 - navigationBarBackgroundColor - navigationBarTextStyle - backgroundColor - backgroundTextStyle - backgroundColorTop - backgroundColorBottom - 全局配置 tabbar 属性: - color - selectedColor - backgroundColor - borderStyle - list - iconPath - selectedIconPath ## 变量配置文件 theme.json@themejson `theme.json` 用于颜色主题相关的变量定义,需要先在 `themeLocation` 中配置 `theme.json` 的路径,否则无法读取变量配置。包含以下属性: | 属性 | 类型 | 必填 | 描述 | | :---- | :----- | :--- | :------------------- | | light | Object | 是 | 浅色模式下的变量定义 | | dark | Object | 是 | 深色模式下的变量定义 | 示例如下: ```json { "light": { "navBgColor": "#f8f8f8", "navTxtStyle": "black" }, "dark": { "navBgColor": "#292929", "navTxtStyle": "white" } } ``` 完成定义后,可在 `pages.json` 中全局配置或页面配置的相关属性中以 `@` 开头引用,例如: ```json // 全局配置 { "globalStyle": { "navigationBarBackgroundColor": "@navBgColor", "navigationBarTextStyle": "@navTxtStyle" } } // 页面配置 { "path": "pages/index/index", "style":{ "navigationBarBackgroundColor": "@navBgColor", "navigationBarTextStyle": "@navTxtStyle" } } ``` 配置完成后,调用相应 api 框架会自动所设属性,展示对应主题下的颜色。 ## 配置示例@themeconfig pages.json(示例省略了主题相关以外的配置项) ```json { "globalStyle": { "navigationBarBackgroundColor": "@navBgColor", "navigationBarTextStyle": "@navTxtStyle", "backgroundColor": "@bgColor", "backgroundTextStyle": "@bgTxtStyle", "backgroundColorTop": "@bgColorTop", "backgroundColorBottom": "@bgColorBottom" }, "tabBar": { "color": "@tabFontColor", "selectedColor": "@tabSelectedColor", "backgroundColor": "@tabBgColor", "borderStyle": "@tabBorderStyle", "list": [ { "iconPath": "@iconPath1", "selectedIconPath": "@selectedIconPath1" }, { "iconPath": "@iconPath2", "selectedIconPath": "@selectedIconPath2" } ] } } ``` theme.json ```json { "light": { "navBgColor": "#f8f8f8", "navTxtStyle": "black", "bgColor": "#ffffff", "bgTxtStyle": "light", "bgColorTop": "#eeeeee", "bgColorBottom": "#efefef", "tabFontColor": "#000000", "tabSelectedColor": "#3cc51f", "tabBgColor": "#ffffff", "tabBorderStyle": "black", "iconPath1": "/static/icon1_light.png", "selectedIconPath1": "/static/selected_icon1_light.png", "iconPath2": "/static/icon2_light.png", "selectedIconPath2": "/static/selected_icon2_light.png" }, "dark": { "navBgColor": "#292929", "navTxtStyle": "white", "bgColor": "#1f1f1f", "bgTxtStyle": "dark", "bgColorTop": "#292929", "bgColorBottom": "#1f1f1f", "tabFontColor": "#ffffff", "tabSelectedColor": "#51a937", "tabBgColor": "#292929", "tabBorderStyle": "white", "iconPath1": "/static/icon1_dark.png", "selectedIconPath1": "/static/selected_icon1_dark.png", "iconPath2": "/static/icon2_dark.png", "selectedIconPath2": "/static/selected_icon2_dark.png" } } ``` ## 获取当前主题@get-theme 如果 `manifest.json` 对应平台配置中声明了`"darkmode": true`,`uni.getSystemInfo` 或 `uni.getSystemInfoSync` 的返回结果中会包含 `theme` 属性,值为 `light` 或 `dark`。 如果 `manifest.json` 对应平台配置未声明`"darkmode": true`,则无法获取到 `theme` 属性(即 theme 为 undefined)。 ## 监听主题切换事件@on-theme-change 支持两种方式: 1. 在 `App.vue` 中写上 `onThemeChange` 生命周期,主题切换时会触发 2. 通过 `uni.onThemeChange` 监听主题变化,`uni.offThemeChange` 取消监听 ## 页面 css 适配@perfers-color-scheme > [css 支持情况](https://caniuse.com/?search=prefers-color-scheme) 在 css 中,支持通过媒体查询 `prefers-color-scheme` 适配不同主题,与 Web 中适配方式一致,例如: ```css /* 一般情况下的样式 start */ .some-background { background: white; } .some-text { color: black; } /* 一般情况下的样式 end */ @media (prefers-color-scheme: dark) { /* DarkMode 下的样式 start */ .some-background { background: #1b1b1b; } .some-text { color: #ffffff; } /* DarkMode 下的样式 end */ } ```