摘要
現在幾乎所有主流應用都支持“深色模式”和“淺色模式”切換,這已經成了用戶習慣。鴻蒙(HarmonyOS)同樣提供了兩種模式(dark / light),并且支持應用根據系統主題切換,或者應用內手動切換。對于開發者來說,如何配置和管理顏色資源,以及如何在代碼里實現動態切換,是必須掌握的技能。
本文會從原理到實戰,帶你實現一個可運行 Demo,并結合實際應用場景,比如電商、閱讀類和社交應用,展示不同的實現方式。
引言
早期很多應用為了“省事”,直接寫死了顏色值,結果一旦系統切換到深色模式,應用就顯得突兀、不協調。鴻蒙的做法比較科學,它提供了 資源限定目錄 的機制:在 resources
文件夾里,你可以為不同的顏色模式準備單獨的資源文件。
這樣一來,應用可以:
- 跟隨系統主題自動切換;
- 也可以在應用內部提供“主題開關”,讓用戶手動切換。
接下來我們分兩部分講:
配置資源文件(Light/Dark 模式的顏色文件);
代碼層實現動態切換。
配置顏色資源
基礎做法
首先在 resources
文件夾下新建 Light/Dark 兩個目錄。方法是右鍵 -> New Resource Directory
-> 勾選 Color Mode,這樣會自動生成 light
和 dark
兩個文件夾。
然后在各自的 element
文件夾下創建 color.json
文件,格式如下:
light/element/color.json
{"color": [{"name": "background","value": "#FFFFFF"},{"name": "font_color","value": "#000000"},{"name": "button_background","value": "#0000FF"}]
}
dark/element/color.json
{"color": [{"name": "background","value": "#000000"},{"name": "font_color","value": "#FFFFFF"},{"name": "button_background","value": "#1E90FF"}]
}
這樣就完成了“顏色資源”的配置。沒配置的情況下,應用會默認使用 base
目錄下的顏色值。
動態主題切換實現
跟隨系統主題
鴻蒙框架會自動根據系統主題選擇 light
或 dark
資源文件。也就是說,你只要準備好顏色資源,就能實現自動切換。
應用內主動切換
有時候,我們想給用戶一個“開關”,讓他們在應用內手動選擇主題。這時需要調用 UIAppearance
相關接口。
下面是一個最小化 Demo:
// Index.ets
import UIAppearance from '@ohos.arkui.UIAppearance';@Entry
@Component
struct Index {@State isDark: boolean = false;build() {Column({ space: 20 }) {Button(this.isDark ? '切換到淺色模式' : '切換到深色模式').onClick(() => {this.isDark = !this.isDark;UIAppearance.setColorMode(this.isDark ? 'dark' : 'light');})Text('當前主題:' + (this.isDark ? '深色模式' : '淺色模式')).fontColor($r('app.color.font_color')).backgroundColor($r('app.color.background')).fontSize(20).padding(20)}.width('100%').height('100%').backgroundColor($r('app.color.background'))}
}
在上面的代碼里:
- 我們定義了一個
isDark
狀態來表示當前主題; - 點擊按鈕后,調用
UIAppearance.setColorMode
主動切換; - 文本和背景顏色都使用資源引用
$r('app.color.xxx')
,這樣能保證跟隨主題變化。
場景應用
電商應用:商品展示
在電商類應用中,白天瀏覽商品時用淺色背景更舒服,晚上則希望用深色模式減少視覺刺激。
Text('¥199.00').fontColor($r('app.color.font_color')).fontSize(24).backgroundColor($r('app.color.background'))
解析:這里字體和背景顏色都是從資源文件里獲取的,系統切換主題時自動生效。
閱讀應用:夜間模式
閱讀類應用通常會提供獨立的“夜間模式開關”。即便系統是淺色模式,用戶也可能選擇在夜間用深色主題。
Toggle({ name: '夜間模式' }, this.isDark).onChange((value: boolean) => {this.isDark = value;UIAppearance.setColorMode(value ? 'dark' : 'light');})
解析:Toggle(開關組件)直接控制主題切換,體驗和閱讀器常見功能一致。
社交應用:個人設置頁面
在社交應用里,主題切換一般放在“設置”頁面。
Row() {Text('深色模式').fontSize(18)Switch({ checked: this.isDark }).onChange((val: boolean) => {this.isDark = val;UIAppearance.setColorMode(val ? 'dark' : 'light');})
}
解析:Switch 控件切換主題,同時更新全局 UI。用戶在“設置”里調整一次,就能影響所有頁面。
常見問題(Q&A)
Q1: 如果沒配置 dark
文件夾會怎樣?
A: 系統會默認使用 base
下的資源,也就是說不會報錯,但主題切換沒效果。
Q2: 為什么有時候顏色不跟隨主題?
A: 很可能是你在組件里直接寫死了顏色值,比如 #FFFFFF
,而不是引用 $r('app.color.xxx')
。
Q3: 應用主動切換和系統主題沖突怎么辦?
A: 一般來說,跟隨系統是默認行為。如果你在應用里提供了“手動開關”,就要在邏輯上優先考慮用戶的選擇。
總結
鴻蒙的動態主題切換本質上依賴于 資源限定目錄 + UIAppearance API。
- 想跟隨系統?準備好
light/dark
資源就行。 - 想主動切換?調用
UIAppearance.setColorMode()
。 - 實際場景里,閱讀、電商、社交等應用都能用上主題切換功能,提升用戶體驗。
寫代碼時最重要的習慣是:不要寫死顏色值,全部走資源引用。這樣一來,主題切換就會自然生效,維護起來也輕松。