問題背景
大部分手機主題上會有深色模式和淺色模式之分,淺色模式一般都是“白底黑字”,深色模式則是“黑底白字”。下圖是華為手機深色模式和淺色模式的界面效果:
- 圖1 淺色模式
- 圖2 深色模式
如何在快應用中實現不同主題模式的適配呢?目前有兩種方案:
-
使用MediaQuery響應式布局能力,自動檢測用戶的設備的系統主題模式,配置不同模式下的css樣式。
-
使用device.getThemeSync,根據獲取的結果選擇不同模式下的css樣式。
解決方案
方案一:MediaQuery響應式布局(推薦)
華為快應用響應式布局中媒體特征(Media Feature)類型提供了prefers-color-scheme字段:檢測用戶的系統主題,支持的屬性值有light和dark模式,對應手機的淺色主題和深色主題。開發者只需要在代碼中配置兩種模式下的css樣式即可,快應用引擎會根據系統主題模式自動調用不同的css。具體實現代碼如下:
<template>
<!-- Only one root node is allowed in template. -->
<div class="container">
<text class="title">
Hello {{title}}
</text>
</div>
</template>
<style>
.container {
flex-direction: column;
justify-content: center;
align-content: center;
align-items: center;
}
.title {
font-size: 100px;
}
/**淺色主題css */
@media (prefers-color-scheme: light) {
.container {
flex-direction: column;
justify-content: center;
align-content: center;
align-items: center;
}
.title {
font-size: 100px;
color: #000000;
}
}
/**深色主題css*/
@media (prefers-color-scheme: dark) {
.container {
flex-direction: column;
justify-content: center;
align-content: center;
align-items: center;
background-color: #000000;
}
.title {
font-size: 100px;
color: #ffffff;
}
}
</style>
<script>
module.exports = {
data: {
title: 'World',
titleBar: ''
},
onInit: function () {
this.titleBar = this.titleBarText;
console.log("onInit titleBar= " + this.titleBar);
this.$page.setTitleBar({ text: this.titleBar });
},
}
</script>
優點:實現簡單,代碼少,開發者只需要配置響應式布局中dark和light的css,無需手動控制調用不同主題模式下的css。
方案二:使用device.getThemeSync
步驟1:獲取設備的主題模式
可使用device.getThemeSync接口返回值獲得,推薦在全局app.ux中實現並將結果保存,對外提供getThemeMode()方法方便每個頁面的ux獲取主題結果。
app.ux代碼如下:
<script>
import device from '@system.device';
module.exports = {
data: {
thememode:''
},
onCreate () {
setTimeout(() => {
let theme=device.getThemeSync();
//{"darkMode":false,"title":"Painted Planet","titleCn":"大地彩繪","author":"EMUI","designer":"EMUI","version":"10.0.7","font":"Default","fontCn":"默認"}
console.info("onCreate theme="+JSON.stringify(theme));
if(theme.darkMode){
this.thememode='darkMode';
}else{
this.thememode='lightMode';
}
}, 100);
},
onDestroy() {
console.info('Application onDestroy');
},
getThemeMode(){
return this.thememode;
}
}
</script>
步驟2:頁面適配
頁面需要實現深色和淺色主題模式下的css樣式,根據 步驟1返回的結果選擇不同的css樣式。下面示例代碼.container和.item是淺色主題下的css樣式, . containerDarkMode和 . itemDarkMode 是深色主題下的css樣式。頁面在生命周期onInit()方法中根據獲取到的設備主題模式選擇不同的css樣式。代碼如下:
<template>
<!-- Only one root node is allowed in template. -->
<div class="{{containercss}}">
<input class="{{itemcss}}" type="button" value="a組件切換頁面" onclick="jumpApage" />
<input class="{{itemcss}}" type="button" value="router接口切換頁面" onclick="jumpRouterPage" />
</div>
</template>
<style>
.container {
flex-direction: column;
margin-top: 50px;
align-content: center;
align-items: center;
}
.containerDarkMode {
flex-direction: column;
margin-top: 50px;
align-content: center;
align-items: center;
background-color: #000000;
}
.item {
background-color: #00bfff;
color: #f8f8ff;
font-size: 37px;
width: 50%;
height: 100px;
margin-bottom: 20px;
}
.itemDarkMode {
background-color: #add8e6;
color: #f8f8ff;
font-size: 37px;
width: 50%;
height: 100px;
margin-bottom: 20px;
}
</style>
<script>
import router from '@system.router';
module.exports = {
data: {
title: 'World',
containercss: 'container',
itemcss: 'item'
},
onInit: function () {
console.info("onInit");
var thememode = this.$app.$def.getThemeMode();
console.info("onInit thememode=" + thememode);
if (thememode === 'darkMode') {
console.info("change dark mode");
this.containercss = 'containerDarkMode';
this.itemcss = 'itemDarkMode';
} else {
this.containercss = 'container';
this.itemcss = 'item';
}
},
onDestroy: function () {
console.info("onDestroy");
},
jumpRouterPage: function () {
router.push({
uri: 'SwitchPage/Router',
params: { body: " test send message" },
})
},
jumpApage: function () {
router.push({
uri: 'SwitchPage/Apage',
params: { body: " test send message" },
})
},
}
</script>
此方案相對方案一稍微復雜一點,需要開發者自己去控制css樣式選擇。
欲了解更多詳情,請參見:
快應用開發指導文檔:https://developer.huawei.com/consumer/cn/doc/development/quickApp-Guides/quickapp-whitepaper
原文鏈接:https://developer.huawei.com/consumer/cn/forum/topic/0201404994231590237?fid=18
原作者:Mayism