在这里插入图片描述

📌 模块概述

外观设置功能是应用个性化的重要组成部分,允许用户深度自定义应用界面元素,主要包括以下可配置项:
主题选择:提供浅色/深色两种基础主题模式,满足不同光线环境下的使用需求
主色调设置:支持通过颜色选择器自定义应用的主色调
字体调整:可设置系统字体大小(小/中/大三级调节)
背景样式:可选纯色或渐变背景效果
这些设置会实时应用到整个应用界面,并持久化保存到本地存储中,确保用户下次打开应用时保持个性化设置。

🔗 完整流程

第一步:选择主题

用户进入外观设置页面后:
在主题选项区看到"浅色"和"深色"两个按钮
当前激活的主题会显示高亮状态(带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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐