鸿蒙多功能工具箱开发实战(五)-主题配色与全局样式管理

前言

良好的视觉设计是提升用户体验的关键。本文将详细讲解HarmonyOS应用的主题配色方案设计、全局样式管理、资源文件组织等核心内容。

一、配色方案设计

1.1 主色调选择

为多功能工具箱设计了以下配色方案:

颜色名称 色值 用途
主色 #4A90E2 主要按钮、强调元素
辅色 #50C878 成功状态、正向反馈
背景色 #F5F5F5 页面背景
卡片色 #FFFFFF 卡片、容器背景
文字色 #333333 主要文字
次要文字 #999999 描述、提示文字
分割线 #E0E0E0 分割线、边框

1.2 分类主题色

每个工具分类使用独立的主题色:

export const CATEGORY_COLORS = {
  CALCULATOR: '#4A90E2',  // 蓝色 - 计算
  CALENDAR: '#E74C3C',    // 红色 - 历法
  CONVERT: '#50C878',     // 绿色 - 换算
  FINANCE: '#FFB347',     // 橙色 - 财务
  MARKET: '#9B59B6',      // 紫色 - 行情
  LIFE: '#1ABC9C'         // 青色 - 生活
}

二、全局样式配置

2.1 创建样式配置文件

创建 common/AppConfig.ets

/**
 * 应用全局配置
 */

// ==================== 主题颜色 ====================
export const THEME_COLORS = {
  // 基础色
  primary: '#4A90E2',
  secondary: '#50C878',
  
  // 背景色
  background: '#F5F5F5',
  card: '#FFFFFF',
  
  // 文字色
  text: '#333333',
  textSecondary: '#999999',
  textHint: '#CCCCCC',
  
  // 边框和分割线
  divider: '#E0E0E0',
  border: '#E8E8E8',
  
  // 状态色
  success: '#27AE60',
  warning: '#F39C12',
  error: '#E74C3C',
  info: '#3498DB'
}

// ==================== 分类颜色 ====================
export const CATEGORY_COLORS = {
  CALCULATOR: '#4A90E2',
  CALENDAR: '#E74C3C',
  CONVERT: '#50C878',
  FINANCE: '#FFB347',
  MARKET: '#9B59B6',
  LIFE: '#1ABC9C'
}

// ==================== 尺寸配置 ====================
export const SIZES = {
  // 字体大小
  fontXS: 10,
  fontSM: 12,
  fontMD: 14,
  fontLG: 16,
  fontXL: 18,
  fontXXL: 24,
  
  // 间距
  spacingXS: 4,
  spacingSM: 8,
  spacingMD: 12,
  spacingLG: 16,
  spacingXL: 20,
  spacingXXL: 24,
  
  // 圆角
  radiusSM: 4,
  radiusMD: 8,
  radiusLG: 12,
  radiusXL: 16,
  radiusRound: 999,
  
  // 阴影
  shadowSM: 4,
  shadowMD: 8,
  shadowLG: 16
}

// ==================== 动画配置 ====================
export const ANIMATION = {
  durationFast: 150,
  durationNormal: 250,
  durationSlow: 400,
  
  curveEase: Curve.Ease,
  curveEaseIn: Curve.EaseIn,
  curveEaseOut: Curve.EaseOut,
  curveLinear: Curve.Linear
}

2.2 使用样式配置

import { THEME_COLORS, SIZES } from '../common/AppConfig'

@Component
struct MyComponent {
  build() {
    Column() {
      Text('标题')
        .fontSize(SIZES.fontXL)
        .fontColor(THEME_COLORS.text)
      
      Text('描述')
        .fontSize(SIZES.fontSM)
        .fontColor(THEME_COLORS.textSecondary)
    }
    .backgroundColor(THEME_COLORS.card)
    .borderRadius(SIZES.radiusLG)
    .padding(SIZES.spacingLG)
  }
}

三、资源文件管理

3.1 资源目录结构

entry/src/main/resources/
├── base/                    # 基础资源
│   ├── element/            # 元素资源
│   │   ├── color.json      # 颜色
│   │   ├── string.json     # 字符串
│   │   ├── float.json      # 浮点数
│   │   └── integer.json    # 整数
│   ├── media/              # 媒体资源
│   │   ├── icon.png        # 图标
│   │   ├── logo.png        # Logo
│   │   └── ...
│   └── profile/            # 配置文件
│       └── main_pages.json
│
├── en_US/                  # 英文资源
│   └── element/
│       └── string.json
│
├── zh_CN/                  # 中文资源
│   └── element/
│       └── string.json
│
└── rawfile/                # 原始文件
    ├── data.json
    └── config.xml

3.2 颜色资源

创建 resources/base/element/color.json

{
  "color": [
    { "name": "primary", "value": "#4A90E2" },
    { "name": "secondary", "value": "#50C878" },
    { "name": "background", "value": "#F5F5F5" },
    { "name": "card", "value": "#FFFFFF" },
    { "name": "text_primary", "value": "#333333" },
    { "name": "text_secondary", "value": "#999999" },
    { "name": "divider", "value": "#E0E0E0" },
    { "name": "success", "value": "#27AE60" },
    { "name": "warning", "value": "#F39C12" },
    { "name": "error", "value": "#E74C3C" }
  ]
}

使用颜色资源:

Column() {
  Text('标题')
}
.backgroundColor($r('app.color.card'))
.fontColor($r('app.color.text_primary'))

3.3 字符串资源

创建 resources/base/element/string.json

{
  "string": [
    { "name": "app_name", "value": "多功能工具箱" },
    { "name": "module_desc", "value": "多功能工具箱应用" },
    { "name": "calculator", "value": "计算工具" },
    { "name": "calendar", "value": "历法工具" },
    { "name": "convert", "value": "换算工具" },
    { "name": "finance", "value": "财务工具" },
    { "name": "market", "value": "行情工具" },
    { "name": "life", "value": "生活工具" }
  ]
}

使用字符串资源:

Text($r('app.string.app_name'))
  .fontSize(24)

3.4 多语言支持

英文资源 resources/en_US/element/string.json

{
  "string": [
    { "name": "app_name", "value": "ToolBox" },
    { "name": "calculator", "value": "Calculator" },
    { "name": "calendar", "value": "Calendar" }
  ]
}

中文资源 resources/zh_CN/element/string.json

{
  "string": [
    { "name": "app_name", "value": "多功能工具箱" },
    { "name": "calculator", "value": "计算工具" },
    { "name": "calendar", "value": "历法工具" }
  ]
}

四、通用样式组件

4.1 通用卡片样式

创建 common/styles/CardStyle.ets

import { THEME_COLORS, SIZES } from '../AppConfig'

/**
 * 卡片样式配置
 */
export class CardStyle {
  // 基础卡片样式
  static base() {
    return {
      backgroundColor: THEME_COLORS.card,
      borderRadius: SIZES.radiusLG,
      shadow: {
        radius: SIZES.shadowSM,
        color: '#1A000000',
        offsetY: 2
      }
    }
  }

  // 凸起卡片样式
  static elevated() {
    return {
      backgroundColor: THEME_COLORS.card,
      borderRadius: SIZES.radiusLG,
      shadow: {
        radius: SIZES.shadowMD,
        color: '#1A000000',
        offsetY: 4
      }
    }
  }
}

4.2 通用按钮样式

创建 common/styles/ButtonStyle.ets

import { THEME_COLORS, SIZES } from '../AppConfig'

/**
 * 按钮样式配置
 */
export class ButtonStyle {
  // 主要按钮
  static primary() {
    return {
      backgroundColor: THEME_COLORS.primary,
      fontColor: '#FFFFFF',
      borderRadius: SIZES.radiusMD,
      fontSize: SIZES.fontMD
    }
  }

  // 次要按钮
  static secondary() {
    return {
      backgroundColor: THEME_COLORS.secondary,
      fontColor: '#FFFFFF',
      borderRadius: SIZES.radiusMD,
      fontSize: SIZES.fontMD
    }
  }

  // 文字按钮
  static text() {
    return {
      backgroundColor: 'transparent',
      fontColor: THEME_COLORS.primary,
      borderRadius: 0,
      fontSize: SIZES.fontMD
    }
  }
}

五、主题切换支持

5.1 定义主题类型

// 主题类型
export enum ThemeMode {
  LIGHT = 'light',
  DARK = 'dark'
}

// 主题配置接口
export interface ThemeConfig {
  background: string
  card: string
  text: string
  textSecondary: string
  divider: string
}

5.2 主题管理

import { ThemeMode, ThemeConfig } from './ThemeTypes'

// 亮色主题
const LIGHT_THEME: ThemeConfig = {
  background: '#F5F5F5',
  card: '#FFFFFF',
  text: '#333333',
  textSecondary: '#999999',
  divider: '#E0E0E0'
}

// 暗色主题
const DARK_THEME: ThemeConfig = {
  background: '#1A1A1A',
  card: '#2D2D2D',
  text: '#FFFFFF',
  textSecondary: '#AAAAAA',
  divider: '#404040'
}

/**
 * 主题管理类
 */
export class ThemeManager {
  private static currentTheme: ThemeMode = ThemeMode.LIGHT

  // 获取当前主题
  static getTheme(): ThemeConfig {
    return this.currentTheme === ThemeMode.LIGHT 
      ? LIGHT_THEME 
      : DARK_THEME
  }

  // 切换主题
  static toggleTheme(): void {
    this.currentTheme = this.currentTheme === ThemeMode.LIGHT 
      ? ThemeMode.DARK 
      : ThemeMode.LIGHT
  }

  // 设置主题
  static setTheme(mode: ThemeMode): void {
    this.currentTheme = mode
  }
}

5.3 使用主题

import { ThemeManager } from '../common/ThemeManager'

@Entry
@Component
struct Index {
  @State theme = ThemeManager.getTheme()

  build() {
    Column() {
      Text('标题')
        .fontColor(this.theme.text)
    }
    .backgroundColor(this.theme.background)
  }
}

六、样式最佳实践

6.1 避免硬编码

❌ 不推荐:

Text('标题')
  .fontSize(18)
  .fontColor('#333333')
  .backgroundColor('#FFFFFF')

✅ 推荐:

import { THEME_COLORS, SIZES } from '../common/AppConfig'

Text('标题')
  .fontSize(SIZES.fontXL)
  .fontColor(THEME_COLORS.text)
  .backgroundColor(THEME_COLORS.card)

6.2 使用@Builder复用样式

@Component
export struct StyledCard {
  @BuilderParam content: () => void

  build() {
    Column() {
      this.content()
    }
    .backgroundColor(THEME_COLORS.card)
    .borderRadius(SIZES.radiusLG)
    .padding(SIZES.spacingLG)
    .shadow({ radius: 8, color: '#1A000000', offsetY: 2 })
  }
}

// 使用
StyledCard() {
  Text('卡片内容')
}

6.3 响应式尺寸

// 根据屏幕宽度适配
import display from '@ohos.display'

function getAdaptiveSize(baseSize: number): number {
  const displayInfo = display.getDefaultDisplaySync()
  const screenWidth = displayInfo.width
  const designWidth = 375  // 设计稿宽度
  
  return baseSize * (screenWidth / designWidth)
}

// 使用
Text('标题')
  .fontSize(getAdaptiveSize(18))

七、完整配置示例

7.1 AppConfig.ets 完整代码

/**
 * 应用全局配置文件
 */

// ==================== 枚举定义 ====================

export enum ToolCategory {
  CALCULATOR = 'calculator',
  CALENDAR = 'calendar',
  CONVERT = 'convert',
  FINANCE = 'finance',
  MARKET = 'market',
  LIFE = 'life'
}

// ==================== 颜色配置 ====================

export const THEME_COLORS = {
  primary: '#4A90E2',
  secondary: '#50C878',
  background: '#F5F5F5',
  card: '#FFFFFF',
  text: '#333333',
  textSecondary: '#999999',
  textHint: '#CCCCCC',
  divider: '#E0E0E0',
  border: '#E8E8E8',
  success: '#27AE60',
  warning: '#F39C12',
  error: '#E74C3C',
  info: '#3498DB'
}

export const CATEGORY_COLORS = {
  CALCULATOR: '#4A90E2',
  CALENDAR: '#E74C3C',
  CONVERT: '#50C878',
  FINANCE: '#FFB347',
  MARKET: '#9B59B6',
  LIFE: '#1ABC9C'
}

// ==================== 尺寸配置 ====================

export const SIZES = {
  fontXS: 10,
  fontSM: 12,
  fontMD: 14,
  fontLG: 16,
  fontXL: 18,
  fontXXL: 24,
  
  spacingXS: 4,
  spacingSM: 8,
  spacingMD: 12,
  spacingLG: 16,
  spacingXL: 20,
  
  radiusSM: 4,
  radiusMD: 8,
  radiusLG: 12,
  
  shadowSM: 4,
  shadowMD: 8
}

// ==================== 接口定义 ====================

export interface CategoryInfo {
  category: ToolCategory
  name: string
  icon: string
  color: string
}

// ==================== 工具函数 ====================

export function getToolCategories(): CategoryInfo[] {
  return [
    { category: ToolCategory.CALCULATOR, name: '计算', icon: '🔢', color: CATEGORY_COLORS.CALCULATOR },
    { category: ToolCategory.CALENDAR, name: '历法', icon: '📅', color: CATEGORY_COLORS.CALENDAR },
    { category: ToolCategory.CONVERT, name: '换算', icon: '🔄', color: CATEGORY_COLORS.CONVERT },
    { category: ToolCategory.FINANCE, name: '财务', icon: '💰', color: CATEGORY_COLORS.FINANCE },
    { category: ToolCategory.MARKET, name: '行情', icon: '📈', color: CATEGORY_COLORS.MARKET },
    { category: ToolCategory.LIFE, name: '生活', icon: '🏠', color: CATEGORY_COLORS.LIFE }
  ]
}

图1 底部导航栏
在这里插入图片描述

八、小结

本文详细讲解了主题配色与全局样式管理,核心要点:

  1. ✅ 配色方案设计原则
  2. ✅ 全局样式配置文件
  3. ✅ 资源文件组织与管理
  4. ✅ 多语言支持
  5. ✅ 通用样式组件封装
  6. ✅ 主题切换支持
  7. ✅ 样式最佳实践

下一篇文章将讲解具体工具功能的开发实现。


系列文章导航
下期预告:鸿蒙多功能工具箱开发实战(六)-亲戚称呼计算器开发

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐