uni-app OS设置自动启用深色模式时始终仅能取得light模式
uni-app OS设置自动启用深色模式时始终仅能取得light模式
信息类别 | 详细信息 |
---|---|
产品分类 | uniapp/App |
PC开发环境操作系统 | Windows |
PC开发环境操作系统版本号 | win10 |
HBuilderX类型 | 正式 |
HBuilderX版本号 | 4.29 |
手机系统 | Android |
手机系统版本号 | Android 10 |
手机厂商 | zte |
手机机型 | 中兴远航10 5G |
页面类型 | vue |
vue版本 | vue3 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
操作步骤:
- manifest.json里已配置app-plus节点下的darkmode为true
- onLaunch里监听theme:
uni.onThemeChange((res)=>{ const {osTheme , theme} = uni.getSystemInfoSync() uni.showModal({ content:`onThemeChange res.theme=${res.theme} ; systemInfo.osTheme=${osTheme} ; systemInfo.theme=${theme}` }) })
- index里设置暗黑模式为跟随系统:
plus.nativeUI.setUIStyle('auto')
- 运行含有上述程序的APP后,返回OS桌面。
- 在操作系统的「设置-显示」里,设置深色模式为自动启用。
- 在保持深色模式自动启用的同时,点击“立即启用” 或者 调整系统时间使之临近预设的启用时间。
- 待确认OS已切换到深色模式后,返回APP,观察showModal弹出的内容,查看onThemeChange的回调参数里的theme 和 此时通过getSystemInfoSync获得的osTheme、theme是否与实际情况一致。
预期结果:
取值应为dark,且showModal的弹窗应为深色风格。
实际结果:
取值实为light,且showModal的弹窗仍为浅色风格。
bug描述:
测了android10、android14,在设置了plus.nativeUI.setUIStyle(‘auto’)之后,发现: 当设置OS的深色模式为自动启用时,再手动切换浅色/深色模式或者待OS成功自动启用深色模式,uniapp通过uni.onThemeChange取得的theme值 或 通过uni.getSystemInfo取得的osTheme、theme值始终为light,且原生界面也无法如期切换到暗黑模式。 若不设置OS的深色模式为自动启用,则上述取值是正常的。
os的主题触发change的时候,你的应用处于开启状态吗?
如果此时你的应用并未开启,那肯定接受不到通知,等你再启动就晚了。
change事件是一个辅助,启动的时候还得自己判断下当前的主题
你好,应用是处于开启状态的。os的深色模式不管是否打开自动启用,都能收到通知,但是,在打开自动启用的情况下,应用收到的通知总是light。
upup
我再配图说明一下使用 hello-darkmode示例工程 复现该问题的步骤。
一、首次运行hello-darkmode 【表现正常】
此时系统尚未启用深色模式(见下图)
hello-darkmode显示当前主题为:auto (见下图)
二、设置自动启用深色模式,启用时间为11:20
三、保持hello-darkmode在后台运行,熄屏,直到11:20。
四、 11:20时,打开手机,打开hello-darkmode和微信,发现均未切换模式,可能均未获取到模式切换消息(这可能是系统的机制问题,再次熄屏,再次打开就会触发,此处不深究)
五、 再次熄屏,再次打开,发现微信已切到深色模式,hello-darkmode识别到模式却为light。【异常】
以下再补充一个更简单的使用hello-darkmode示例工程的复现流程,实际就是楼上的复现的极简版。
一、打开系统深色模式的自动启用,并同时直接把深色模式启用。
二、下图获取到的主题始终为light
请关注一下此问题,谢谢。
请关注一下此问题,谢谢。
请关注一下此问题,谢谢。
请关注一下此问题,谢谢。
请关注一下此问题,谢谢。
请关注一下此问题,谢谢。
在uni-app中,处理系统深色模式(Dark Mode)和浅色模式(Light Mode)的切换通常需要依赖uni.getSystemInfoSync
方法来获取系统当前的主题模式,并结合CSS变量或类名来控制页面的样式。如果你发现即使在系统设置为自动启用深色模式时,uni-app始终只能取得light模式,可能是因为uni-app的配置或代码处理逻辑有误。
以下是一个基本的代码案例,展示了如何在uni-app中检测并响应系统主题模式的变化:
- 在
App.vue
中初始化主题模式:
<script>
export default {
onLaunch() {
this.updateTheme();
// 监听系统主题变化(如果平台支持)
if (typeof window !== 'undefined' && 'matchMedia' in window) {
const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
mediaQueryList.addEventListener('change', this.updateTheme);
}
},
methods: {
updateTheme() {
const systemInfo = uni.getSystemInfoSync();
let theme = 'light';
if (systemInfo.theme === 'dark' ||
(typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
theme = 'dark';
}
// 设置全局样式变量或类名
uni.setStorageSync('theme', theme);
this.$set(uni.$store.state, 'theme', theme); // 假设你使用了Vuex
document.documentElement.setAttribute('data-theme', theme);
}
}
}
</script>
<style>
/* 定义基础样式 */
:root {
--bg-color-light: #ffffff;
--bg-color-dark: #333333;
--text-color-light: #000000;
--text-color-dark: #ffffff;
}
[data-theme="light"] {
background-color: var(--bg-color-light);
color: var(--text-color-light);
}
[data-theme="dark"] {
background-color: var(--bg-color-dark);
color: var(--text-color-dark);
}
</style>
- 在组件中使用主题:
确保你的组件样式可以响应data-theme
属性的变化,无需在每个组件中单独处理主题切换逻辑。
- 注意事项:
- 上述代码假设你在
App.vue
中处理主题切换,并通过document.documentElement.setAttribute
设置全局的data-theme
属性。 - 如果你使用Vuex管理状态,可以在Vuex中存储当前主题,并在组件中通过计算属性访问。
uni.getSystemInfoSync
获取的系统信息可能不包含theme
字段(取决于uni-app版本和平台支持),因此建议使用window.matchMedia
作为备用方案。- 确保你的页面和组件样式使用了CSS变量,以便能够根据
data-theme
属性动态调整样式。