快应用 夜间模式适配
从 Android 10 开始,系统加入了夜间模式(也有被称为深色模式、暗色模式)的原生支持。快应用也同步引入了此特性,方便开发者更好地适配夜间模式。
在这一篇教程,我们将从简单的主题模式配置入门,到控制自动反色开关与手动配置夜间模式的样式,逐步掌握夜间模式的最佳实践。
注意:
- 夜间模式仅在
Android 10
以上版本的手机支持,如果要查看效果,请确保拥有合适版本的手机,且快应用平台版本号在1070
以上。另外,快应用打包工具 hap-toolkit 的版本号要在0.6.15
版本以上。(可通过命令hap -v
查看版本号) - vivo 手机暂不支持快应用的夜间模式适配
通过本篇教程,我们将学会:
效果展示
配置 app 的主题模式
快应用的主题模式支持三种:
- 跟随系统主题模式
- 固定日间模式
- 固定夜间模式
其中,跟随系统主题模式
这一项选中时,当系统切换日间
、夜间
两种主题模式,快应用也会跟随变换主题模式。
了解 3 种主题模式的区别后,现在我们可以尝试在快应用配置主题模式
啦。
步骤:
在manifest.json
的display
属性,添加themeMode
值即可,默认为-1
(跟随系统主题模式),详情请查看 manifest 文档
示例代码:
"display": {
"themeMode": -1,
}
themeMode 可填入值:
参数值 | 意义 |
---|---|
-1 | 跟随系统主题模式 |
0 | 固定日间模式 |
1 | 固定夜间模式 |
获取 app 的主题模式值
如果需要针对特定的主题模式做适配逻辑,我们就需要获取当前的主题模式值了
步骤:
通过调用@system.configuration
的getThemeMode
方法即可获取,详情可参考 configuration 文档
返回值:
参数值 | 意义 |
---|---|
0 | 当前主题为日间模式 |
1 | 当前主题为夜间模式 |
示例代码:
import configuration from '@system.configuration'
export default {
getTheme() {
const themeMode = configuration.getThemeMode()
console.log(`Theme mode is ${themeMode} now~`)
}
}
系统主题模式切换的回调
想象一个用户常见的场景,比如说在小说阅读时,用户切换系统主题到夜间模式,应用需弹出提示“进入夜间模式啦”。这个时候,就需要监听主题模式切换了。
步骤:
- 在页面代码如
index.ux
里,实现快应用页面级别的onConfigurationChanged
回调,监听配置切换事件。 - 当 type 为
themeMode
时,此时回调即为主题模式切换的回调
详情可参考 script文档 的onConfigurationChanged
一节
注意:
- 因为在
onConfigurationChanged
只能拿到type
值,所以开发者如果需要在回调时同时获取主题模式值来判断,可以参考上一节教程,手动获取themeMode
值 - 即使在 manifest.json 配置了
themeMode
为 0(固定日间模式)或 1(固定夜间模式),用户切换系统主题时快应用不会有界面变化,但仍会触发onConfigurationChanged
回调
示例代码:
// index.ux
import configuration from '@system.configuration'
export default {
onConfigurationChanged(params) {
const { type = '' } = params
if (type === 'themeMode') {
const themeMode = configuration.getThemeMode()
console.log(`themeMode has changed! And now theme mode is ${themeMode}.`)
} else {
console.log(`other type of config has changed, type is : ${type}.`)
}
}
}
ForceDark 开关
看了我们上面的效果图,也许你会好奇,只是设置了皮肤模式,为什么我的快应用就自动在夜间模式可以反色呢?而且效果还这么好!
其实,这是 Android 10 以上系统提供的一个功能,叫Force Dark
。开启了Force Dark
的安卓应用,就会在夜间模式自动反色,达到十分简单且效果不赖的 APP 夜间模式效果,详情可查看 Android 的深色主题背景文档的"Force Dark"一节
而快应用也把Force Dark
的特性在 1070 以上的版本开始加入支持。
我们只需要按照配置 app 的主题模式教程,将 themeMode 设为 -1(跟随系统主题模式)或 1(固定夜间模式),即可在夜间模式查看反色效果,非常方便。
然而,因为Force Dark
反色的样式由 Android 底层自动计算,我们是无法手动修改的。因此,根据需求场景,我们可能需要手动关闭反色效果,或指定夜间模式的样式。
在这一节,我们将学习如何关闭反色效果。
ForceDark
的开关有 3 个级别:
ForceDark 开关基本原则
在快应用中,ForceDark
开关,除了直接影响自己的反色表现,也同样影响其所有子元素的反色表现。
父子元素的层级顺序:APP 级别 > 页面级别 > 组件级别 > 子组件级别
具体规则如下:
- 如果父元素设置为
true
,子元素设置为false
,则子元素的表现是false
;子元素设置为true
,则子元素的表现为true
- 如果父元素设置为
false
,子元素无论设置为false
或true
,表现都是false
应用级别的 forceDark
应用级别的forceDark
开关,可配置此快应用所有页面的自动反色开关。
步骤:
在manifest.json
的display
属性下可配置forceDark
属性(属性为驼峰命名)
参数值:
默认为true
(开启),可选值:true
(开启),false
(关闭)
示例代码:
"display": {
"themeMode": -1,
"forceDark": true
}
单页面级别的 forceDark
页面级别的forceDark
开关,可配置特定页面的自动反色开关。
步骤:
在manifest.json
的display
属性下的pages
数组的页面节点,可配置forceDark
属性(属性为驼峰命名)
参数值:
默认为true
(开启),可选值:true
(开启),false
(关闭)
示例代码:
"router": {
"pages": {
"Demo": {
"titleBarText": "示例页",
"forceDark": false
},
}
}
组件级别的 forcedark
组件级别的forcedark
开关,可以配置该组件的自动反色开关
步骤:
在组件标签里配置forcedark
属性(属性为全小写命名)
参数值:
默认为true
(开启),可选值:true
(开启),false
(关闭)
示例代码:
// force-dark-demo.ux
<template>
<div>
<text forcedark="false">关闭了自动反色的文字</text>
<text>默认开启了自动反色的文字</text>
<div>
</template>
注意点:
- 组件级别的
forcedark
属性为全小写!与manifest.json
的配置项为驼峰的forceDark不一样!请注意书写! - 子节点的
forcedark
遵守 ForceDark 开关基本原则 的简介,需要注意父子元素的forcedark开关的影响 span
组件不支持forcedark
开关,它只能依赖父元素的forcedark
参数值控制开关,并且当父元素为span
的时候,继续往上找,直至找到父元素为a
或text
元素截止video
、camera
、map
、custommarker
、canvas
组件均不支持设置forcedark
参数,也不会响应父元素的forcedark
设置
通过媒体查询配置指定主题模式的样式
当我们对安卓夜间模式的反色处理不太满意时,上一节我们学习了如何手动关闭反色效果。这一节,我们会使用媒体查询(media query
),去配置指定主题模式的样式
媒体查询,即media query
,快应用在1070
版本开始提供支持,详情可查看 样式文档 。
如果需要使用media query
实现夜间模式的样式配置,则查询条件是prefers-color-scheme
注意: prefers-color-scheme
的媒体查询仅在 Android 10+手机支持
支持参数:
light
系统主题模式为日间模式时查询生效dark
系统主题模式为夜间模式时查询生效
示例代码:
<style>
.box {
width:100px;
height:100px;
background-color:black;
}
@media (prefers-color-scheme: dark) {
.box {
background: white;
}
}
</style>
总结
夜间模式作为新的软件交互界面的探索,快应用在 Android 10+手机上提供了支持与丰富的可配置项。开发者配合这篇教程,可以更好更快捷地,实现快应用的夜间模式形态。