欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

在这里插入图片描述

📌 概述

应用设置模块允许用户配置BugTracker Pro应用的各种参数。在Cordova与OpenHarmony混合开发框架下,这个模块提供了完整的设置界面,用户可以在其中修改应用的行为和外观。应用设置功能的设计目标是为用户提供灵活的配置选项,使应用能够适应不同用户的需求。

应用设置模块采用了分类设置的设计,将不同类型的设置分别放在不同的部分中,使得用户可以轻松找到他们需要的设置。

🔗 完整流程

第一步:设置加载

当用户打开应用设置页面时,系统首先从本地存储中加载现有的设置。系统会读取localStorage中保存的设置数据,然后将其显示在设置表单中。

设置加载包括读取各种设置项的值,比如语言、主题、通知设置等。

第二步:设置修改

用户可以在设置表单中修改各种设置。当用户修改设置时,系统会实时更新表单中的值,并在用户点击保存按钮时将设置保存到本地存储。

第三步:设置应用

当用户保存设置后,系统会将设置应用到应用中。比如,如果用户修改了主题设置,系统会立即改变应用的外观。

🔧 Web代码实现

HTML结构

<div id="settings-page" class="page">
  <div class="page-header">
    <h1 class="page-title">应用设置</h1>
  </div>

  <div class="page-content">
    <form id="settings-form" class="form">
      <!-- 基本设置 -->
      <div class="settings-section">
        <h2>基本设置</h2>
        
        <div class="form-group">
          <label for="language" class="form-label">语言</label>
          <select id="language" class="form-select">
            <option value="zh">中文</option>
            <option value="en">English</option>
          </select>
        </div>

        <div class="form-group">
          <label for="timezone" class="form-label">时区</label>
          <select id="timezone" class="form-select">
            <option value="UTC+8">UTC+8 (中国)</option>
            <option value="UTC+0">UTC+0 (伦敦)</option>
            <option value="UTC-5">UTC-5 (纽约)</option>
          </select>
        </div>
      </div>

      <!-- 外观设置 -->
      <div class="settings-section">
        <h2>外观设置</h2>
        
        <div class="form-group">
          <label for="theme" class="form-label">主题</label>
          <select id="theme" class="form-select" onchange="settingsModule.applyTheme()">
            <option value="light">浅色</option>
            <option value="dark">深色</option>
            <option value="auto">自动</option>
          </select>
        </div>

        <div class="form-group">
          <label for="font-size" class="form-label">字体大小</label>
          <select id="font-size" class="form-select">
            <option value="small"></option>
            <option value="normal">正常</option>
            <option value="large"></option>
          </select>
        </div>
      </div>

      <!-- 通知设置 -->
      <div class="settings-section">
        <h2>通知设置</h2>
        
        <div class="form-group">
          <label class="checkbox-label">
            <input type="checkbox" id="enable-notifications" class="form-checkbox" />
            启用通知
          </label>
        </div>

        <div class="form-group">
          <label class="checkbox-label">
            <input type="checkbox" id="notify-on-update" class="form-checkbox" />
            Bug更新时通知
          </label>
        </div>

        <div class="form-group">
          <label class="checkbox-label">
            <input type="checkbox" id="notify-on-deadline" class="form-checkbox" />
            接近截止时间时通知
          </label>
        </div>
      </div>

      <!-- 数据设置 -->
      <div class="settings-section">
        <h2>数据设置</h2>
        
        <div class="form-group">
          <label class="checkbox-label">
            <input type="checkbox" id="auto-backup" class="form-checkbox" />
            自动备份
          </label>
        </div>

        <div class="form-group">
          <label for="backup-interval" class="form-label">备份间隔</label>
          <select id="backup-interval" class="form-select">
            <option value="daily">每天</option>
            <option value="weekly">每周</option>
            <option value="monthly">每月</option>
          </select>
        </div>

        <div class="form-actions">
          <button type="button" class="btn btn-default" onclick="settingsModule.manualBackup()">
            手动备份
          </button>
          <button type="button" class="btn btn-default" onclick="settingsModule.clearCache()">
            清空缓存
          </button>
        </div>
      </div>

      <!-- 提交按钮 -->
      <div class="form-actions">
        <button type="submit" class="btn btn-primary">保存设置</button>
        <button type="button" class="btn btn-default" onclick="settingsModule.resetSettings()">
          恢复默认
        </button>
      </div>
    </form>
  </div>
</div>

HTML结构包含了基本设置、外观设置、通知设置和数据设置四个部分。

JavaScript逻辑

// 应用设置模块
class SettingsModule {
  constructor() {
    this.defaultSettings = {
      language: 'zh',
      timezone: 'UTC+8',
      theme: 'dark',
      fontSize: 'normal',
      enableNotifications: true,
      notifyOnUpdate: true,
      notifyOnDeadline: true,
      autoBackup: true,
      backupInterval: 'weekly'
    };
    
    this.init();
  }

  async init() {
    this.loadSettings();
    this.bindEvents();
  }

  loadSettings() {
    const settings = this.getSettings();
    
    // 填充表单
    document.getElementById('language').value = settings.language;
    document.getElementById('timezone').value = settings.timezone;
    document.getElementById('theme').value = settings.theme;
    document.getElementById('font-size').value = settings.fontSize;
    document.getElementById('enable-notifications').checked = settings.enableNotifications;
    document.getElementById('notify-on-update').checked = settings.notifyOnUpdate;
    document.getElementById('notify-on-deadline').checked = settings.notifyOnDeadline;
    document.getElementById('auto-backup').checked = settings.autoBackup;
    document.getElementById('backup-interval').value = settings.backupInterval;
  }

  bindEvents() {
    const form = document.getElementById('settings-form');
    form.addEventListener('submit', (e) => this.handleSubmit(e));
  }

  async handleSubmit(e) {
    e.preventDefault();
    
    try {
      // 收集设置数据
      const settings = {
        language: document.getElementById('language').value,
        timezone: document.getElementById('timezone').value,
        theme: document.getElementById('theme').value,
        fontSize: document.getElementById('font-size').value,
        enableNotifications: document.getElementById('enable-notifications').checked,
        notifyOnUpdate: document.getElementById('notify-on-update').checked,
        notifyOnDeadline: document.getElementById('notify-on-deadline').checked,
        autoBackup: document.getElementById('auto-backup').checked,
        backupInterval: document.getElementById('backup-interval').value
      };
      
      // 保存设置
      this.saveSettings(settings);
      
      // 应用设置
      this.applySettings(settings);
      
      utils.showSuccess('设置已保存');
      
    } catch (error) {
      console.error('保存设置失败:', error);
      utils.showError('保存设置失败');
    }
  }

  getSettings() {
    const stored = localStorage.getItem('app_settings');
    return stored ? JSON.parse(stored) : this.defaultSettings;
  }

  saveSettings(settings) {
    localStorage.setItem('app_settings', JSON.stringify(settings));
  }

  applySettings(settings) {
    // 应用主题
    this.applyTheme();
    
    // 应用字体大小
    this.applyFontSize(settings.fontSize);
    
    // 应用语言
    this.applyLanguage(settings.language);
  }

  applyTheme() {
    const theme = document.getElementById('theme').value;
    const root = document.documentElement;
    
    if (theme === 'dark') {
      root.style.setProperty('--bg-color', '#1a1a1a');
      root.style.setProperty('--text-color', '#ffffff');
    } else if (theme === 'light') {
      root.style.setProperty('--bg-color', '#ffffff');
      root.style.setProperty('--text-color', '#333333');
    }
  }

  applyFontSize(size) {
    const root = document.documentElement;
    
    if (size === 'small') {
      root.style.setProperty('--font-size', '12px');
    } else if (size === 'large') {
      root.style.setProperty('--font-size', '16px');
    } else {
      root.style.setProperty('--font-size', '14px');
    }
  }

  applyLanguage(language) {
    // 这里可以实现多语言支持
    console.log('应用语言:', language);
  }

  async manualBackup() {
    try {
      utils.showLoading('正在备份...');
      
      // 执行备份
      const allBugs = await db.getAllBugs();
      const backupData = {
        timestamp: new Date().toISOString(),
        bugs: allBugs
      };
      
      // 保存备份
      const backupKey = `backup_${Date.now()}`;
      localStorage.setItem(backupKey, JSON.stringify(backupData));
      
      utils.hideLoading();
      utils.showSuccess('备份成功');
      
    } catch (error) {
      console.error('备份失败:', error);
      utils.hideLoading();
      utils.showError('备份失败');
    }
  }

  async clearCache() {
    if (confirm('确定要清空缓存吗?')) {
      try {
        // 清空缓存
        localStorage.clear();
        utils.showSuccess('缓存已清空');
      } catch (error) {
        console.error('清空缓存失败:', error);
        utils.showError('清空缓存失败');
      }
    }
  }

  resetSettings() {
    if (confirm('确定要恢复默认设置吗?')) {
      this.saveSettings(this.defaultSettings);
      this.loadSettings();
      this.applySettings(this.defaultSettings);
      utils.showSuccess('已恢复默认设置');
    }
  }
}

// 初始化应用设置模块
const settingsModule = new SettingsModule();

JavaScript代码实现了完整的设置管理功能,包括加载、保存、应用设置等。

CSS样式

/* 设置部分 */
.settings-section {
  padding: 20px;
  background: white;
  border-radius: 4px;
  margin-bottom: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.settings-section h2 {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 14px;
  font-weight: 500;
}

/* 复选框标签 */
.checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 14px;
}

.form-checkbox {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

🔌 OpenHarmony原生代码

// entry/src/main/ets/plugins/SettingsPlugin.ets
import { hilog } from '@kit.PerformanceAnalysisKit';
import { preferences } from '@kit.ArkData';
import { common } from '@kit.AbilityKit';

const TAG: string = '[SettingsPlugin]';
const DOMAIN: number = 0xFF00;

export class SettingsPlugin {
  static async saveSettings(success: Function, error: Function, args: any[]): Promise<void> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      const settings = args[0];
      
      // 保存设置到系统偏好设置
      const preferences_instance = await preferences.getPreferences(context, 'app_settings');
      
      for (const key in settings) {
        await preferences_instance.put(key, settings[key]);
      }
      
      await preferences_instance.flush();
      
      hilog.info(DOMAIN, TAG, '设置已保存');
      success('设置已保存');
    } catch (err) {
      hilog.error(DOMAIN, TAG, `保存设置失败: ${err}`);
      error('保存设置失败');
    }
  }

  static async getSettings(success: Function, error: Function): Promise<void> {
    try {
      const context = getContext(this) as common.UIAbilityContext;
      
      // 从系统偏好设置读取
      const preferences_instance = await preferences.getPreferences(context, 'app_settings');
      const settings = await preferences_instance.getAll();
      
      hilog.info(DOMAIN, TAG, '获取设置成功');
      success(settings);
    } catch (err) {
      hilog.error(DOMAIN, TAG, `获取设置失败: ${err}`);
      error('获取设置失败');
    }
  }
}

Web-Native通信

// 设置通信类
class SettingsBridge {
  static saveSettings(settings) {
    return new Promise((resolve, reject) => {
      if (window.cordova) {
        cordova.exec(
          (result) => {
            console.log('设置已保存:', result);
            resolve(result);
          },
          (error) => {
            console.error('保存设置失败:', error);
            reject(error);
          },
          'SettingsPlugin',
          'saveSettings',
          [settings]
        );
      } else {
        reject('Cordova未加载');
      }
    });
  }

  static getSettings() {
    return new Promise((resolve, reject) => {
      if (window.cordova) {
        cordova.exec(
          (settings) => {
            console.log('获取设置:', settings);
            resolve(settings);
          },
          (error) => {
            console.error('获取设置失败:', error);
            reject(error);
          },
          'SettingsPlugin',
          'getSettings',
          []
        );
      } else {
        reject('Cordova未加载');
      }
    });
  }
}

📝 总结

应用设置模块是BugTracker Pro应用中用于配置应用行为和外观的重要功能。在Cordova与OpenHarmony混合开发框架下,它提供了完整的设置界面和管理功能。通过灵活的设置选项,用户可以根据自己的需求定制应用,这大大提高了应用的易用性。

模块采用了模块化的设计,各个功能都是独立的,易于维护和扩展。通过Cordova插件与原生代码的交互,我们可以实现更高级的设置功能。这充全展示了混合开发框架的优势。

Logo

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

更多推荐