HarmonyOS 鸿蒙Next深色模式适配持久化实现方式
HarmonyOS 鸿蒙Next深色模式适配持久化实现方式 调用ApplicationContext.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK)将应用配色方案设为深色模式后,仅运行期间有效。退出应用重新进入后,设置丢失,深色模式失效。如何实现设置深色模式后,下次进入应用能保留配置?
ApplicationContext.setColorMode()
只是临时设置应用的配色模式,不会持久化到存储中。应用重启后,系统会恢复为默认配置。
解决方案
需要结合 数据持久化 + 应用启动时恢复配置 来实现。HarmonyOS 提供了多种数据持久化方式,推荐使用 Preferences(首选项)。
完整实现方案
方案一:使用 Preferences
- 创建配置管理工具类
// utils/ThemeManager.ets
import { preferences } from '@kit.ArkData';
import { ConfigurationConstant } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
export class ThemeManager {
private static instance: ThemeManager;
private dataPreferences: preferences.Preferences | null = null;
private context: common.Context | null = null;
private readonly PREFERENCE_NAME = 'app_settings';
private readonly KEY_COLOR_MODE = 'color_mode';
// 单例模式
public static getInstance(): ThemeManager {
if (!ThemeManager.instance) {
ThemeManager.instance = new ThemeManager();
}
return ThemeManager.instance;
}
// 初始化(在应用启动时调用)
async init(context: common.Context): Promise<void> {
this.context = context;
try {
// 获取 Preferences 实例
this.dataPreferences = await preferences.getPreferences(
context,
this.PREFERENCE_NAME
);
console.info('ThemeManager 初始化成功');
} catch (error) {
console.error('ThemeManager 初始化失败:', error);
}
}
// 保存深色模式配置
async saveColorMode(colorMode: ConfigurationConstant.ColorMode): Promise<void> {
if (!this.dataPreferences) {
console.error('Preferences 未初始化');
return;
}
try {
// 保存到 Preferences
await this.dataPreferences.put(this.KEY_COLOR_MODE, colorMode);
// 持久化到磁盘
await this.dataPreferences.flush();
console.info('深色模式配置已保存:', colorMode);
} catch (error) {
console.error('保存深色模式配置失败:', error);
}
}
// 获取保存的深色模式配置
async getColorMode(): Promise<ConfigurationConstant.ColorMode> {
if (!this.dataPreferences) {
console.error('Preferences 未初始化');
return ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;
}
try {
// 从 Preferences 读取
const colorMode = await this.dataPreferences.get(
this.KEY_COLOR_MODE,
ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
) as ConfigurationConstant.ColorMode;
console.info('读取到的深色模式配置:', colorMode);
return colorMode;
} catch (error) {
console.error('读取深色模式配置失败:', error);
return ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;
}
}
// 应用深色模式配置
async applyColorMode(colorMode: ConfigurationConstant.ColorMode): Promise<void> {
if (!this.context) {
console.error('Context 未初始化');
return;
}
try {
// 获取 ApplicationContext
const applicationContext = this.context.getApplicationContext();
// 设置深色模式
applicationContext.setColorMode(colorMode);
// 保存配置
await this.saveColorMode(colorMode);
console.info('深色模式已应用:', colorMode);
} catch (error) {
console.error('应用深色模式失败:', error);
}
}
// 恢复保存的深色模式配置(在应用启动时调用)
async restoreColorMode(): Promise<void> {
if (!this.context) {
console.error('Context 未初始化');
return;
}
try {
// 读取保存的配置
const savedColorMode = await this.getColorMode();
// 如果有保存的配置,则应用
if (savedColorMode !== ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET) {
const applicationContext = this.context.getApplicationContext();
applicationContext.setColorMode(savedColorMode);
console.info('已恢复深色模式配置:', savedColorMode);
} else {
console.info('未找到保存的深色模式配置,使用默认设置');
}
} catch (error) {
console.error('恢复深色模式配置失败:', error);
}
}
// 切换深色模式
async toggleColorMode(): Promise<void> {
const currentMode = await this.getColorMode();
// 切换模式
const newMode = currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK
? ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT
: ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
// 应用新模式
await this.applyColorMode(newMode);
}
// 检查当前是否为深色模式
async isDarkMode(): Promise<boolean> {
const colorMode = await this.getColorMode();
return colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
}
}
- 在 EntryAbility 中初始化并恢复配置
// entryability/EntryAbility.ets
import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { ThemeManager } from '../utils/ThemeManager';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', 'Ability onDestroy');
}
async onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(0x0000, 'testTag', 'Ability onWindowStageCreate');
// ✅ 关键步骤1:初始化 ThemeManager
const themeManager = ThemeManager.getInstance();
await themeManager.init(this.context);
// ✅ 关键步骤2:恢复保存的深色模式配置
await themeManager.restoreColorMode();
// 加载主页面
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s',
JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
});
}
onWindowStageDestroy(): void {
hilog.info(0x0000, 'testTag', 'Ability onWindowStageDestroy');
}
onForeground(): void {
hilog.info(0x0000, 'testTag', 'Ability onForeground');
}
onBackground(): void {
hilog.info(0x0000, 'testTag', 'Ability onBackground');
}
}
- 在页面中使用
// pages/Index.ets
import { ConfigurationConstant } from '@kit.AbilityKit';
import { ThemeManager } from '../utils/ThemeManager';
@Entry
@Component
struct Index {
@State isDarkMode: boolean = false;
async aboutToAppear() {
// 获取当前深色模式状态
const themeManager = ThemeManager.getInstance();
this.isDarkMode = await themeManager.isDarkMode();
}
build() {
Column({ space: 20 }) {
Text('深色模式设置')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Row({ space: 10 }) {
Text('当前模式:')
.fontSize(18)
Text(this.isDarkMode ? '深色' : '浅色')
.fontSize(18)
.fontColor(this.isDarkMode ? Color.White : Color.Black)
}
// 切换按钮
Button('切换深色模式')
.onClick(async () => {
const themeManager = ThemeManager.getInstance();
await themeManager.toggleColorMode();
// 更新状态
this.isDarkMode = await themeManager.isDarkMode();
})
// 直接设置深色模式
Button('设置为深色模式')
.onClick(async () => {
const themeManager = ThemeManager.getInstance();
await themeManager.applyColorMode(
ConfigurationConstant.ColorMode.COLOR_MODE_DARK
);
this.isDarkMode = true;
})
// 直接设置浅色模式
Button('设置为浅色模式')
.onClick(async () => {
const themeManager = ThemeManager.getInstance();
await themeManager.applyColorMode(
ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT
);
this.isDarkMode = false;
})
// 跟随系统设置
Button('跟随系统')
.onClick(async () => {
const themeManager = ThemeManager.getInstance();
await themeManager.applyColorMode(
ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
);
// 重新读取当前状态
this.isDarkMode = await themeManager.isDarkMode();
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.padding(20)
.backgroundColor(this.isDarkMode ? '#1F1F1F' : '#F5F5F5')
}
}
方案二:使用 AppStorage(应用内全局状态 + Preferences)
如果需要在应用内多个页面共享深色模式状态,可以结合 AppStorage:
// utils/ThemeManagerWithAppStorage.ets
import { preferences } from '@kit.ArkData';
import { ConfigurationConstant } from '@kit.AbilityKit';
import { common } from '@kit.AbilityKit';
export class ThemeManagerWithAppStorage {
private static instance: ThemeManagerWithAppStorage;
private dataPreferences: preferences.Preferences | null = null;
private context: common.Context | null = null;
private readonly PREFERENCE_NAME = 'app_settings';
private readonly KEY_COLOR_MODE = 'color_mode';
private readonly APP_STORAGE_KEY = 'isDarkMode';
public static getInstance(): ThemeManagerWithAppStorage {
if (!ThemeManagerWithAppStorage.instance) {
ThemeManagerWithAppStorage.instance = new ThemeManagerWithAppStorage();
}
return ThemeManagerWithAppStorage.instance;
}
async init(context: common.Context): Promise<void> {
this.context = context;
try {
this.dataPreferences = await preferences.getPreferences(
context,
this.PREFERENCE_NAME
);
console.info('ThemeManagerWithAppStorage 初始化成功');
} catch (error) {
console.error('ThemeManagerWithAppStorage 初始化失败:', error);
}
}
// 应用深色模式并保存到 AppStorage
async applyColorMode(colorMode: ConfigurationConstant.ColorMode): Promise<void> {
if (!this.context || !this.dataPreferences) {
console.error('未初始化');
return;
}
try {
// 设置系统配色
const applicationContext = this.context.getApplicationContext();
applicationContext.setColorMode(colorMode);
// 保存到 Preferences
await this.dataPreferences.put(this.KEY_COLOR_MODE, colorMode);
await this.dataPreferences.flush();
// 更新 AppStorage(全局状态)
const isDark = colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
AppStorage.setOrCreate(this.APP_STORAGE_KEY, isDark);
console.info('深色模式已应用并保存:', colorMode);
} catch (error) {
console.error('应用深色模式失败:', error);
}
}
// 恢复配置
async restoreColorMode(): Promise<void> {
if (!this.context || !this.dataPreferences) {
console.error('未初始化');
return;
}
try {
// 读取保存的配置
const savedColorMode = await this.dataPreferences.get(
this.KEY_COLOR_MODE,
ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
) as ConfigurationConstant.ColorMode;
if (savedColorMode !== ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET) {
// 应用配置
const applicationContext = this.context.getApplicationContext();
applicationContext.setColorMode(savedColorMode);
// 更新 AppStorage
const isDark = savedColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
AppStorage.setOrCreate(this.APP_STORAGE_KEY, isDark);
console.info('已恢复深色模式配置:', savedColorMode);
}
} catch (error) {
console.error('恢复深色模式配置失败:', error);
}
}
}
在页面中使用 AppStorage:
@Entry
@Component
struct Index {
// 从 AppStorage 读取全局状态
@StorageLink('isDarkMode') isDarkMode: boolean = false;
build() {
Column({ space: 20 }) {
Text('深色模式: ' + (this.isDarkMode ? '开启' : '关闭'))
.fontSize(24)
Button('切换深色模式')
.onClick(async () => {
const themeManager = ThemeManagerWithAppStorage.getInstance();
const newMode = this.isDarkMode
? ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT
: ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
await themeManager.applyColorMode(newMode);
// AppStorage 会自动更新 this.isDarkMode
})
}
.width('100%')
.height('100%')
.backgroundColor(this.isDarkMode ? '#1F1F1F' : '#F5F5F5')
}
}
关键要点总结
必须做的:
- 在 Ability 启动时恢复配置
async onWindowStageCreate(windowStage: window.WindowStage) { await themeManager.init(this.context); await themeManager.restoreColorMode(); // 关键! // … }
- 每次修改配置时都要保存
applicationContext.setColorMode(colorMode); // 临时设置 await themeManager.saveColorMode(colorMode); // 持久化保存
- 使用 Preferences 的 flush() 方法确保写入磁盘
await dataPreferences.put(KEY_COLOR_MODE, colorMode); await dataPreferences.flush(); // 确保持久化
常见错误:
- 只调用 setColorMode() 不保存
- 没有在 Ability 启动时恢复配置
- 忘记调用 flush() 导致配置未写入磁盘
更多关于HarmonyOS 鸿蒙Next深色模式适配持久化实现方式的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next深色模式适配持久化可通过AbilityStage和UIAbility结合Preferences数据管理实现。在应用启动时,使用Preferences读取存储的主题设置,调用windowClass.setWindowBackgroundColor或UIService.setAppTheme动态切换。持久化存储利用Preferences.put()方法保存用户选择的模式,确保应用重启后主题一致。具体实现涉及获取窗口实例、监听系统主题变化,并在onWindowStageCreate生命周期中应用配置。
在HarmonyOS Next中,要实现深色模式设置的持久化,可以使用Preferences或分布式数据对象来保存用户选择的配色模式。以下是具体实现步骤:
-
使用Preferences存储配置:
- 在设置深色模式时,将配置值写入Preferences:
import preferences from '[@ohos](/user/ohos).data.preferences'; let preferences = await preferences.getPreferences(context, 'colorModePrefs'); await preferences.put('colorMode', ConfigurationConstant.ColorMode.COLOR_MODE_DARK); await preferences.flush();- 应用启动时读取Preferences中的配置并应用:
let savedMode = await preferences.get('colorMode', ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT); ApplicationContext.setColorMode(savedMode); -
结合应用生命周期管理:
- 在
onCreate或应用初始化阶段加载保存的配置,确保启动时立即生效。
- 在
这种方式可以确保用户退出应用后再次进入时,深色模式配置仍然保留。

