前言
代碼運行環境:全部基于HarmonyOs NEXT
DevEco Studio:Build Version: 5.0.3.900
API:12
modelVersion:5.0.0
無論是Android還是iOS,在系統設置中,都有著深色和淺色兩種外觀模式,同樣,鴻蒙系統中也存在這樣的外觀切換,如何讓自己的應用,跟隨著系統的模式進行動態切換呢?目前系統給我們提供了兩種方式可以實現,一種是資源形式,一種是動態的代碼形式。
資源形式實現
所謂資源形式,就是深色和淺色各有一套樣式,比如顏色,淺色有一個,深色也有一個,當系統模式切換之后,便主動尋找對應模式下的顏色,同樣,放到其它資源上也是類似。
首先,在resources資源下,定義出淺色模式對應的深色資源,命名為dark,把我們對應的顏色,或者圖片,一一放到對應的模式下。
簡單案例
一個很簡單的頁面,顏色和背景均選取資源下定義好的。
@Entry
@Component
struct Index {
build() {
Column() {
Text("鴻蒙開發:跟著系統深淺色適配")
.fontSize(18)
.fontColor($r("app.color.title_color"))
.margin({ top: 10 })
Text("無論是Android還是iOS,在系統設置中,都有著深色和淺色兩種外觀模式,同樣,鴻蒙系統中也存在這樣的外觀切換,如何讓自己的應用,跟隨著系統的模式進行動態切換呢?目前系統給我們提供了兩種方式可以實現,一種是資源形式,一種是動態的代碼形式。")
.fontSize(16)
.fontColor($r("app.color.desc_color"))
.margin({ top: 20 })
}.backgroundColor($r("app.color.start_window_background"))
.width("100%")
.height("100%")
.padding({ left: 20, right: 20 })
}
}
淺色模式
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
},
{
"name": "title_color",
"value": "#222222"
},
{
"name": "desc_color",
"value": "#666666"
}
]
}
深色模式
{
"color": [
{
"name": "start_window_background",
"value": "#000000"
},
{
"name": "title_color",
"value": "#ffffff"
},
{
"name": "desc_color",
"value": "#e8e8e8"
}
]
}
實際效果
淺色模式
深色模式
圖片資源適配
圖片和顏色是類似的,淺色和深色放在對應的模式下即可。
Image($r('app.media.test'))
.width(50)
代碼形式
除了資源的形式之外,我們還可以通過代碼的方式進行實現,代碼的實現方式,需要我們監聽系統的模式切換,然后,根據當前的模式,設置不同的資源樣式即可。
監聽系統的深色和淺色模式切換:
首先,針對當前的模式,先進行保存,這里使用的是AppStorage,保存當前模式,主要是初始化進來需要針對性的設置。
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
AppStorage.setOrCreate('colorMode', this.context.config.colorMode)
}
除了默認的之外,當系統的模式發生變化的時候,也需要進行保存,我們可以在在 AbilityStage 的 onConfigurationUpdate() 方法中獲取最新的顏色模式同步更新到AppStorage中。
onConfigurationUpdate(newConfig: Configuration): void {
AppStorage.setOrCreate('colorMode', newConfig.colorMode)
hilog.info(0x0000, 'testTag', 'the newConfig.colorMode');
}
還是上邊的那個案例,我們在UI頁面進行動態的監聽模式改變。
@Entry
@Component
struct Index {
@State titleColor?: ResourceColor = undefined
@State descColor?: ResourceColor = undefined
@State bgColor?: ResourceColor = undefined
@StorageProp('colorMode') @Watch('onColorModeChange') currentMode: number =
ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
aboutToAppear(): void {
this.onColorModeChange()
}
onColorModeChange(): void {
if (this.currentMode == ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT) {
//淺色模式
this.bgColor = "#ffffff"
this.titleColor = "#222222"
this.descColor = "#666666"
} else {
//深色模式
this.bgColor = "#000000"
this.titleColor = "#ffffff"
this.descColor = "#e8e8e8"
}
}
build() {
Column() {
Text("鴻蒙開發:跟著系統深淺色適配")
.fontSize(18)
.fontColor(this.titleColor)
.margin({ top: 10 })
Text("無論是Android還是iOS,在系統設置中,都有著深色和淺色兩種外觀模式,同樣,鴻蒙系統中也存在這樣的外觀切換,如何讓自己的應用,跟隨著系統的模式進行動態切換呢?目前系統給我們提供了兩種方式可以實現,一種是資源形式,一種是動態的代碼形式。")
.fontSize(16)
.fontColor(this.descColor)
.margin({ top: 20 })
}
.backgroundColor(this.bgColor)
.width("100%")
.height("100%")
.padding({ left: 20, right: 20 })
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}
}
可以發現,效果和上面的資源形式是一樣的。
相關總結
無論是資源模式,還是代碼模式,都可以實現跟隨系統模式的改變而改變,如果,你不想跟著系統改變,有兩種方式,第一種方式是正常開發就行,默認就是淺色模式,但是,如果你想默認深色模式,那么就需要進行代碼設置了,設置之后,就不會跟著系統的改變而改變了。
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK)