外观设置 Cordova 与 OpenHarmony 混合开发实战
本文介绍了应用外观设置功能的实现方案,包含Web端和OpenHarmony原生代码实现。该功能允许用户自定义主题(浅色/深色)和主色调,并通过数据库或文件保存用户偏好设置。Web端使用JavaScript实现主题切换和颜色选择,OpenHarmony端则通过ArkTS开发原生插件,提供JavaScript代理接口。两种实现都包含设置保存和应用逻辑,展示了混合开发中外观定制的完整流程。
📌 模块概述
外观设置功能是应用个性化的重要组成部分,允许用户深度自定义应用界面元素,主要包括以下可配置项:
主题选择:提供浅色/深色两种基础主题模式,满足不同光线环境下的使用需求
主色调设置:支持通过颜色选择器自定义应用的主色调
字体调整:可设置系统字体大小(小/中/大三级调节)
背景样式:可选纯色或渐变背景效果
这些设置会实时应用到整个应用界面,并持久化保存到本地存储中,确保用户下次打开应用时保持个性化设置。
🔗 完整流程
第一步:选择主题
用户进入外观设置页面后:
在主题选项区看到"浅色"和"深色"两个按钮
当前激活的主题会显示高亮状态(带active类名)
点击任意主题按钮触发主题切换
第二步:应用主题
系统执行以下操作:
立即更新HTML根元素的data-theme属性
动态加载对应的CSS变量值
所有使用CSS变量的组件会自动更新样式
显示操作成功的Toast提示
第三步:保存偏好
系统进行持久化存储:
获取当前所有设置项
更新其中的theme字段
将完整设置对象写入本地数据库
在IndexedDB/文件系统中保存为JSON格式
🔧 Web代码实现
// 扩展的外观设置渲染方法
async renderAppearance() {
const settings = await noteDB.getSettings();
const fontSizeOptions = [
{value: 'small', label: '小'},
{value: 'medium', label: '中'},
{value: 'large', label: '大'}
];
return `
<div class="page active">
<div class="page-header">
<h1 class="page-title">🎨 外观设置</h1>
</div>
<div class="appearance-settings">
<!-- 主题设置 -->
<div class="form-group">
<label>主题模式</label>
<div class="theme-options">
<button class="theme-btn ${settings.theme === 'light' ? 'active' : ''}"
onclick="app.setTheme('light')">
<i class="icon-sun"></i> 浅色
</button>
<button class="theme-btn ${settings.theme === 'dark' ? 'active' : ''}"
onclick="app.setTheme('dark')">
<i class="icon-moon"></i> 深色
</button>
</div>
</div>
<!-- 主色调设置 -->
<div class="form-group">
<label>主色调</label>
<div class="color-picker-wrapper">
<input type="color" id="primary-color"
value="${settings.primaryColor || '#409EFF'}"
onchange="app.setPrimaryColor(this.value)">
<span class="color-value">${settings.primaryColor || '#409EFF'}</span>
</div>
</div>
<!-- 字体大小设置 -->
<div class="form-group">
<label>字体大小</label>
<div class="font-size-options">
${fontSizeOptions.map(opt => `
<button class="size-btn ${settings.fontSize === opt.value ? 'active' : ''}"
onclick="app.setFontSize('${opt.value}')">
${opt.label}
</button>
`).join('')}
</div>
</div>
</div>
</div>
`;
}
// 增强的主题设置方法
async setTheme(theme) {
try {
// 1. 更新数据库
const settings = await noteDB.getSettings();
settings.theme = theme;
await noteDB.updateSettings(settings);
// 2. 应用主题样式
const root = document.documentElement;
root.setAttribute('data-theme', theme);
// 3. 根据主题自动调整辅助颜色
const isDark = theme === 'dark';
root.style.setProperty('--bg-color', isDark ? '#1a1a1a' : '#ffffff');
root.style.setProperty('--text-color', isDark ? '#f0f0f0' : '#333333');
Utils.showToast(`已切换至${theme === 'light' ? '浅色' : '深色'}主题`, 'success');
} catch (error) {
console.error('主题切换失败:', error);
Utils.showToast('主题切换失败', 'error');
}
}
// 新增字体设置方法
async setFontSize(size) {
try {
const settings = await noteDB.getSettings();
settings.fontSize = size;
await noteDB.updateSettings(settings);
document.documentElement.style.setProperty('--font-size',
size === 'small' ? '14px' : size === 'medium' ? '16px' : '18px');
Utils.showToast(`字体大小已调整为${size === 'small' ? '小' : size === 'medium' ? '中' : '大'}`, 'success');
} catch (error) {
console.error('字体设置失败:', error);
}
}
🔌 OpenHarmony 原生代码
// 增强的AppearancePlugin.ets
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
import { fileIo } from '@kit.CoreFileKit';
import { preferences } from '@kit.DataPreferencesKit';
@NativeComponent
export class AppearancePlugin {
private context: common.UIAbilityContext;
private static readonly SETTINGS_KEY = 'app_appearance_settings';
constructor(context: common.UIAbilityContext) {
this.context = context;
}
public init(webviewController: webview.WebviewController): void {
webviewController.registerJavaScriptProxy(
new AppearanceJSProxy(this),
'appearancePlugin',
['setTheme', 'setPrimaryColor', 'setFontSize', 'getSettings']
);
}
// 获取所有设置
public getSettings(): Promise<string> {
return new Promise((resolve) => {
preferences.getPreferences(this.context, 'user_settings')
.then(pref => {
return pref.get(AppearancePlugin.SETTINGS_KEY, '{}');
})
.then(settings => {
resolve(settings);
})
.catch(() => {
resolve('{}');
});
});
}
// 更新设置
private updateSettings(settings: object): Promise<boolean> {
return new Promise((resolve) => {
preferences.getPreferences(this.context, 'user_settings')
.then(pref => {
return pref.put(AppearancePlugin.SETTINGS_KEY, JSON.stringify(settings));
})
.then(() => resolve(true))
.catch(e => {
console.error('Save settings failed:', e);
resolve(false);
});
});
}
public setTheme(theme: string): Promise<boolean> {
return this.getSettings().then(current => {
const settings = JSON.parse(current);
settings.theme = theme;
return this.updateSettings(settings);
});
}
public setPrimaryColor(color: string): Promise<boolean> {
return this.getSettings().then(current => {
const settings = JSON.parse(current);
settings.primaryColor = color;
return this.updateSettings(settings);
});
}
public setFontSize(size: string): Promise<boolean> {
return this.getSettings().then(current => {
const settings = JSON.parse(current);
settings.fontSize = size;
return this.updateSettings(settings);
});
}
}
// 增强的代理类
class AppearanceJSProxy {
private plugin: AppearancePlugin;
constructor(plugin: AppearancePlugin) {
this.plugin = plugin;
}
async getSettings() {
return await this.plugin.getSettings();
}
setTheme(theme: string): Promise<boolean> {
return this.plugin.setTheme(theme);
}
setPrimaryColor(color: string): Promise<boolean> {
return this.plugin.setPrimaryColor(color);
}
setFontSize(size: string): Promise<boolean> {
return this.plugin.setFontSize(size);
}
}
📝 总结
外观设置模块通过以下技术方案实现了完整的个性化功能:
跨平台实现:
Web端使用CSS变量动态更新样式
OpenHarmony使用Preferences数据持久化
通过JavaScript桥接实现双向通信
实时响应:
所有样式变更立即生效
支持系统级主题变化监听(如跟随系统暗黑模式)
可扩展架构:
设置项数据结构设计为键值对形式
新增配置项只需扩展设置对象和UI控件
用户体验优化:
提供视觉反馈(Toast提示)
保持设置项的高亮状态
自动处理异常情况
这套方案适用于大多数需要个性化定制的应用场景,开发者可以根据实际需求进一步扩展设置项。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)