在这里插入图片描述
在这里插入图片描述

一、项目概述

1.1 应用背景

色彩系统是鸿蒙设计语言的重要组成部分,它为应用提供了统一的视觉风格和品牌识别度。鸿蒙设计语言采用蓝色作为主色调,搭配绿色、红色、橙色、紫色等辅助色,形成了一套完整的色彩体系。

本文以「鸿蒙特性展示台」应用为例,详细讲解如何使用 Flutter 实现鸿蒙色彩系统,包括主色调、辅助色、中性色的定义和使用,以及如何实现主题适配和深色模式支持。

1.2 技术栈
技术点 说明
Color Flutter 颜色类,用于定义颜色值
ColorScheme Material Design 配色方案,用于主题管理
ThemeData 主题数据类,用于配置应用主题
Container 基础容器组件,用于展示颜色
BoxDecoration 装饰器,用于设置背景颜色
TextStyle 文本样式类,用于配置文本颜色
MediaQuery 媒体查询,用于获取系统主题模式
1.3 界面效果

应用的设计语言页面展示了完整的鸿蒙色彩系统:

┌─────────────────────────────────────────────────────────────────┐
│                      鸿蒙色彩系统                                │
│  主色调                                                         │
│  [●#0A59F7] [●#4080FF] [●#69A0FF] [●#93B5FF] [●#BED7FF]       │
│                                                                 │
│  辅助色                                                         │
│  [●#00B42A] [●#FA5151] [●#FA8C16] [●#722ED1] [●#13C2C2]       │
│                                                                 │
│  中性色                                                         │
│  [●#1A1A1A] [●#434343] [●#666666] [●#999999] [●#F5F7FA]       │
├─────────────────────────────────────────────────────────────────┤
│                      鸿蒙字体规范                                │
│  超大标题  32px  HarmonyOS 设计语言                            │
│  大标题    28px  HarmonyOS 设计语言                            │
│  标题      24px  HarmonyOS 设计语言                            │
│  副标题    20px  HarmonyOS 设计语言                            │
│  正文      16px  HarmonyOS 设计语言                            │
│  正文小    14px  HarmonyOS 设计语言                            │
│  辅助文字  13px  HarmonyOS 设计语言                            │
│  标签      12px  HarmonyOS 设计语言                            │
│  小字      11px  HarmonyOS 设计语言                            │
├─────────────────────────────────────────────────────────────────┤
│                      组件样式                                    │
│  [主按钮]        [次按钮]        [描边按钮]                     │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  请输入内容                                              │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  请输入密码                                              │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
│  开启通知  ●──────────○    深色模式  ○──────────○              │
├─────────────────────────────────────────────────────────────────┤
│                      阴影与层级                                  │
│  [无阴影]  [小阴影]  [中阴影]  [大阴影]                         │
│                                                                 │
│  [4px]     [8px]     [12px]    [16px]                          │
└─────────────────────────────────────────────────────────────────┘

二、核心代码解析

2.1 DesignLanguagePage 主组件

这是设计语言页面的核心组件,展示了鸿蒙色彩系统、字体规范、组件样式和阴影层级:

class DesignLanguagePage extends StatelessWidget {
  const DesignLanguagePage({super.key});

  
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _buildColorPalette(),
          const SizedBox(height: 20),
          _buildTypographyDemo(),
          const SizedBox(height: 20),
          _buildComponentStyles(),
          const SizedBox(height: 20),
          _buildShadowAndElevation(),
        ],
      ),
    );
  }
}

代码解析:

  • 使用 SingleChildScrollView 包裹页面内容,支持滚动
  • 使用 Column 垂直排列四个主要展示区域:色彩面板、字体演示、组件样式和阴影层级
2.2 色彩面板组件

色彩面板组件展示鸿蒙设计语言的完整色彩系统:

Widget _buildColorPalette() {
  return Container(
    padding: const EdgeInsets.all(20),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(16),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withValues(alpha: 0.06),
          blurRadius: 12,
          offset: const Offset(0, 4),
        ),
      ],
    ),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          '鸿蒙色彩系统',
          style: TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.w600,
            color: Color(0xFF1A1A1A),
          ),
        ),
        const SizedBox(height: 16),
        _buildColorSection('主色调', [
          const Color(0xFF0A59F7),
          const Color(0xFF4080FF),
          const Color(0xFF69A0FF),
          const Color(0xFF93B5FF),
          const Color(0xFFBED7FF),
        ], ['#0A59F7', '#4080FF', '#69A0FF', '#93B5FF', '#BED7FF']),
        const SizedBox(height: 20),
        _buildColorSection('辅助色', [
          const Color(0xFF00B42A),
          const Color(0xFFFA5151),
          const Color(0xFFFA8C16),
          const Color(0xFF722ED1),
          const Color(0xFF13C2C2),
        ], ['#00B42A', '#FA5151', '#FA8C16', '#722ED1', '#13C2C2']),
        const SizedBox(height: 20),
        _buildColorSection('中性色', [
          const Color(0xFF1A1A1A),
          const Color(0xFF434343),
          const Color(0xFF666666),
          const Color(0xFF999999),
          const Color(0xFFF5F7FA),
        ], ['#1A1A1A', '#434343', '#666666', '#999999', '#F5F7FA']),
      ],
    ),
  );
}

代码解析:

  1. 容器样式

    • 使用白色背景和圆角设计
    • 添加阴影效果增强立体感
  2. 标题

    • 显示"鸿蒙色彩系统"标题,使用大号字体和加粗样式
  3. 色彩分区

    • 调用 _buildColorSection 方法分别构建主色调、辅助色和中性色三个区域
    • 每个区域包含多个颜色块和对应的十六进制颜色值
2.3 色彩分区组件

色彩分区组件展示单个色彩类别的多个颜色:

Widget _buildColorSection(String title, List<Color> colors, List<String> hexValues) {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text(
        title,
        style: const TextStyle(
          fontSize: 14,
          fontWeight: FontWeight.w500,
          color: Color(0xFF434343),
        ),
      ),
      const SizedBox(height: 12),
      Row(
        children: colors.asMap().entries.map((entry) {
          final index = entry.key;
          final color = entry.value;
          return Expanded(
            child: Container(
              margin: index < colors.length - 1 ? const EdgeInsets.only(right: 8) : EdgeInsets.zero,
              child: Column(
                children: [
                  Container(
                    height: 48,
                    decoration: BoxDecoration(
                      color: color,
                      borderRadius: BorderRadius.circular(8),
                      border: Border.all(
                        color: const Color(0xFFF0F0F0),
                        width: 1,
                      ),
                    ),
                  ),
                  const SizedBox(height: 6),
                  Text(
                    hexValues[index],
                    style: const TextStyle(
                      fontSize: 11,
                      color: Color(0xFF999999),
                    ),
                  ),
                ],
              ),
            ),
          );
        }).toList(),
      ),
    ],
  );
}

代码解析:

  1. 参数设计

    • title:色彩类别名称(如主色调、辅助色)
    • colors:颜色列表
    • hexValues:颜色的十六进制值列表
  2. 布局实现

    • 使用 RowExpanded 实现颜色块的等宽分布
    • 颜色块之间使用 margin 添加间距
  3. 颜色展示

    • 使用 Container 展示颜色块,高度为 48px
    • 颜色块下方显示对应的十六进制颜色值
2.4 字体演示组件

字体演示组件展示鸿蒙设计语言的字体规范:

Widget _buildTypographyDemo() {
  return Container(
    padding: const EdgeInsets.all(20),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(16),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withValues(alpha: 0.06),
          blurRadius: 12,
          offset: const Offset(0, 4),
        ),
      ],
    ),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          '鸿蒙字体规范',
          style: TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.w600,
            color: Color(0xFF1A1A1A),
          ),
        ),
        const SizedBox(height: 16),
        _buildTypographyRow('超大标题', 32, FontWeight.w700),
        _buildTypographyRow('大标题', 28, FontWeight.w600),
        _buildTypographyRow('标题', 24, FontWeight.w600),
        _buildTypographyRow('副标题', 20, FontWeight.w500),
        _buildTypographyRow('正文', 16, FontWeight.w400),
        _buildTypographyRow('正文小', 14, FontWeight.w400),
        _buildTypographyRow('辅助文字', 13, FontWeight.w400),
        _buildTypographyRow('标签', 12, FontWeight.w500),
        _buildTypographyRow('小字', 11, FontWeight.w400),
      ],
    ),
  );
}

代码解析:

  1. 容器样式

    • 使用白色背景和圆角设计
    • 添加阴影效果增强立体感
  2. 标题

    • 显示"鸿蒙字体规范"标题
  3. 字体层级

    • 调用 _buildTypographyRow 方法构建不同层级的字体示例
    • 从超大标题(32px)到小字(11px),共9个层级
2.5 字体行组件

字体行组件展示单个字体层级的样式:

Widget _buildTypographyRow(String label, double fontSize, FontWeight fontWeight) {
  return Padding(
    padding: const EdgeInsets.symmetric(vertical: 8),
    child: Row(
      children: [
        SizedBox(
          width: 70,
          child: Text(
            label,
            style: const TextStyle(
              fontSize: 12,
              color: Color(0xFF999999),
            ),
          ),
        ),
        const SizedBox(width: 16),
        SizedBox(
          width: 60,
          child: Text(
            '${fontSize}px',
            style: const TextStyle(
              fontSize: 12,
              color: Color(0xFF999999),
            ),
          ),
        ),
        const SizedBox(width: 16),
        Expanded(
          child: Text(
            'HarmonyOS 设计语言',
            style: TextStyle(
              fontSize: fontSize,
              fontWeight: fontWeight,
              color: const Color(0xFF1A1A1A),
            ),
            overflow: TextOverflow.ellipsis,
            maxLines: 1,
          ),
        ),
      ],
    ),
  );
}

代码解析:

  1. 参数设计

    • label:字体层级名称(如超大标题、正文)
    • fontSize:字体大小
    • fontWeight:字体粗细
  2. 布局实现

    • 使用 Row 水平排列标签、字号和示例文本
    • 标签和字号使用固定宽度,示例文本使用 Expanded 自适应
  3. 文本样式

    • 示例文本使用指定的字体大小和粗细
    • 添加 TextOverflow.ellipsis 防止文本溢出
2.6 组件样式组件

组件样式组件展示按钮、输入框和开关的样式:

Widget _buildComponentStyles() {
  return Container(
    padding: const EdgeInsets.all(20),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(16),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withValues(alpha: 0.06),
          blurRadius: 12,
          offset: const Offset(0, 4),
        ),
      ],
    ),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          '组件样式',
          style: TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.w600,
            color: Color(0xFF1A1A1A),
          ),
        ),
        const SizedBox(height: 16),
        _buildButtonSection(),
        const SizedBox(height: 20),
        _buildInputSection(),
        const SizedBox(height: 20),
        _buildSwitchSection(),
      ],
    ),
  );
}

代码解析:

  • 包含三个子组件:按钮样式、输入框样式和开关样式
2.7 按钮样式组件

按钮样式组件展示三种按钮样式:

Widget _buildButtonSection() {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      const Text(
        '按钮样式',
        style: TextStyle(
          fontSize: 14,
          fontWeight: FontWeight.w500,
          color: Color(0xFF434343),
        ),
      ),
      const SizedBox(height: 12),
      Row(
        children: [
          Expanded(
            child: ElevatedButton(
              onPressed: () {},
              style: ElevatedButton.styleFrom(
                backgroundColor: const Color(0xFF0A59F7),
                foregroundColor: Colors.white,
                elevation: 0,
                minimumSize: const Size(double.infinity, 44),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
              ),
              child: const Text('主按钮'),
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: ElevatedButton(
              onPressed: () {},
              style: ElevatedButton.styleFrom(
                backgroundColor: const Color(0xFFF5F7FA),
                foregroundColor: const Color(0xFF1A1A1A),
                elevation: 0,
                minimumSize: const Size(double.infinity, 44),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
              ),
              child: const Text('次按钮'),
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: OutlinedButton(
              onPressed: () {},
              style: OutlinedButton.styleFrom(
                backgroundColor: Colors.transparent,
                foregroundColor: const Color(0xFF0A59F7),
                side: const BorderSide(
                  color: Color(0xFF0A59F7),
                  width: 1,
                ),
                minimumSize: const Size(double.infinity, 44),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
              ),
              child: const Text('描边按钮'),
            ),
          ),
        ],
      ),
    ],
  );
}

代码解析:

  1. 主按钮

    • 背景色使用主色调 #0A59F7
    • 文字颜色为白色
    • 圆角为 12px
  2. 次按钮

    • 背景色使用浅灰色 #F5F7FA
    • 文字颜色为黑色
    • 圆角为 12px
  3. 描边按钮

    • 背景色为透明
    • 边框颜色使用主色调 #0A59F7
    • 文字颜色为蓝色
2.8 输入框样式组件

输入框样式组件展示普通输入框和密码输入框:

Widget _buildInputSection() {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      const Text(
        '输入框样式',
        style: TextStyle(
          fontSize: 14,
          fontWeight: FontWeight.w500,
          color: Color(0xFF434343),
        ),
      ),
      const SizedBox(height: 12),
      TextField(
        decoration: InputDecoration(
          hintText: '请输入内容',
          filled: true,
          fillColor: const Color(0xFFF5F7FA),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(12),
            borderSide: BorderSide.none,
          ),
          contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        ),
      ),
      const SizedBox(height: 8),
      TextField(
        obscureText: true,
        decoration: InputDecoration(
          hintText: '请输入密码',
          filled: true,
          fillColor: const Color(0xFFF5F7FA),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(12),
            borderSide: BorderSide.none,
          ),
          contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        ),
      ),
    ],
  );
}

代码解析:

  1. 普通输入框

    • 使用浅灰色背景 #F5F7FA
    • 圆角为 12px
    • 无边框设计
  2. 密码输入框

    • 设置 obscureText: true 隐藏输入内容
    • 其他样式与普通输入框一致
2.9 开关样式组件

开关样式组件展示两个开关示例:

Widget _buildSwitchSection() {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      const Text(
        '开关样式',
        style: TextStyle(
          fontSize: 14,
          fontWeight: FontWeight.w500,
          color: Color(0xFF434343),
        ),
      ),
      const SizedBox(height: 12),
      Row(
        children: [
          Expanded(
            child: Row(
              children: [
                const Text(
                  '开启通知',
                  style: TextStyle(
                    fontSize: 15,
                    color: Color(0xFF1A1A1A),
                  ),
                ),
                const Spacer(),
                Switch(
                  value: true,
                  onChanged: (value) {},
                  activeThumbColor: const Color(0xFF0A59F7),
                ),
              ],
            ),
          ),
          const SizedBox(width: 24),
          Expanded(
            child: Row(
              children: [
                const Text(
                  '深色模式',
                  style: TextStyle(
                    fontSize: 15,
                    color: Color(0xFF1A1A1A),
                  ),
                ),
                const Spacer(),
                Switch(
                  value: false,
                  onChanged: (value) {},
                  activeThumbColor: const Color(0xFF0A59F7),
                ),
              ],
            ),
          ),
        ],
      ),
    ],
  );
}

代码解析:

  1. 开关配置

    • 激活状态的 thumb 颜色使用主色调 #0A59F7
    • 第一个开关为开启状态,第二个为关闭状态
  2. 布局实现

    • 使用 RowExpanded 实现两个开关的等宽分布
    • 每个开关包含文本标签和开关组件
2.10 阴影与层级组件

阴影与层级组件展示不同级别的阴影效果和圆角规范:

Widget _buildShadowAndElevation() {
  return Container(
    padding: const EdgeInsets.all(20),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(16),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withValues(alpha: 0.06),
          blurRadius: 12,
          offset: const Offset(0, 4),
        ),
      ],
    ),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          '阴影与层级',
          style: TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.w600,
            color: Color(0xFF1A1A1A),
          ),
        ),
        const SizedBox(height: 16),
        Row(
          children: [
            Expanded(
              child: _buildShadowCard(0, '无阴影'),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildShadowCard(4, '小阴影'),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildShadowCard(8, '中阴影'),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildShadowCard(12, '大阴影'),
            ),
          ],
        ),
        const SizedBox(height: 20),
        const Text(
          '圆角规范',
          style: TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.w500,
            color: Color(0xFF434343),
          ),
        ),
        const SizedBox(height: 12),
        Row(
          children: [
            Expanded(
              child: _buildRadiusCard(4, '4px'),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildRadiusCard(8, '8px'),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildRadiusCard(12, '12px'),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildRadiusCard(16, '16px'),
            ),
          ],
        ),
      ],
    ),
  );
}

代码解析:

  1. 阴影展示

    • 调用 _buildShadowCard 方法展示四种阴影级别(无阴影、小阴影、中阴影、大阴影)
    • 阴影的 blurRadius 分别为 0、4、8、12
  2. 圆角展示

    • 调用 _buildRadiusCard 方法展示四种圆角大小(4px、8px、12px、16px)
2.11 阴影卡片组件

阴影卡片组件展示单个阴影级别:

Widget _buildShadowCard(double blurRadius, String label) {
  return Container(
    padding: const EdgeInsets.all(16),
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(12),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withValues(alpha: 0.06),
          blurRadius: blurRadius,
          offset: const Offset(0, 2),
        ),
      ],
    ),
    child: Column(
      children: [
        const SizedBox(height: 20),
        Text(
          label,
          style: const TextStyle(
            fontSize: 13,
            fontWeight: FontWeight.w500,
            color: Color(0xFF666666),
          ),
        ),
      ],
    ),
  );
}

代码解析:

  • 根据传入的 blurRadius 参数设置阴影模糊半径
  • 阴影颜色使用黑色,透明度为 0.06
2.12 圆角卡片组件

圆角卡片组件展示单个圆角大小:

Widget _buildRadiusCard(double radius, String label) {
  return Container(
    padding: const EdgeInsets.all(16),
    decoration: BoxDecoration(
      color: const Color(0xFFF5F7FA),
      borderRadius: BorderRadius.circular(radius),
    ),
    child: Column(
      children: [
        const SizedBox(height: 20),
        Text(
          label,
          style: const TextStyle(
            fontSize: 13,
            fontWeight: FontWeight.w500,
            color: Color(0xFF666666),
          ),
        ),
      ],
    ),
  );
}

代码解析:

  • 根据传入的 radius 参数设置圆角半径
  • 使用浅灰色背景突出显示圆角效果

三、主题配置实现

3.1 应用主题配置

在应用入口配置全局主题:

class HarmonyOSFeatureGallery extends StatelessWidget {
  const HarmonyOSFeatureGallery({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '鸿蒙特性展示台',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF0A59F7),
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      home: const MainPage(),
    );
  }
}

代码解析:

  1. 主题数据

    • 使用 ThemeData 配置应用主题
    • 设置 useMaterial3: true 使用 Material Design 3 设计规范
  2. 配色方案

    • 使用 ColorScheme.fromSeed 生成配色方案
    • seedColor 设置为主色调 #0A59F7
    • brightness 设置为 Brightness.light 使用浅色主题
3.2 自定义颜色常量

为了方便使用,可以将鸿蒙色彩系统定义为常量:

class HarmonyOSColors {
  static const Color primary = Color(0xFF0A59F7);
  static const Color primaryLight = Color(0xFF4080FF);
  static const Color primaryLighter = Color(0xFF69A0FF);
  static const Color primaryLightest = Color(0xFF93B5FF);
  static const Color primaryLightest2 = Color(0xFFBED7FF);

  static const Color success = Color(0xFF00B42A);
  static const Color error = Color(0xFFFA5151);
  static const Color warning = Color(0xFFFA8C16);
  static const Color purple = Color(0xFF722ED1);
  static const Color cyan = Color(0xFF13C2C2);

  static const Color textPrimary = Color(0xFF1A1A1A);
  static const Color textSecondary = Color(0xFF434343);
  static const Color textTertiary = Color(0xFF666666);
  static const Color textQuaternary = Color(0xFF999999);

  static const Color background = Color(0xFFFFFFFF);
  static const Color backgroundLight = Color(0xFFF5F7FA);
  static const Color border = Color(0xFFF0F0F0);
}

代码解析:

  • 将颜色分类定义为静态常量
  • 包括主色调系列、辅助色系列和中性色系列
  • 方便在整个应用中统一使用
3.3 深色模式支持

为了支持深色模式,可以配置 darkTheme

MaterialApp(
  title: '鸿蒙特性展示台',
  debugShowCheckedModeBanner: false,
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(
      seedColor: const Color(0xFF0A59F7),
      brightness: Brightness.light,
    ),
    useMaterial3: true,
  ),
  darkTheme: ThemeData(
    colorScheme: ColorScheme.fromSeed(
      seedColor: const Color(0xFF0A59F7),
      brightness: Brightness.dark,
    ),
    useMaterial3: true,
  ),
  themeMode: ThemeMode.system,
  home: const MainPage(),
);

代码解析:

  1. 深色主题

    • 使用 darkTheme 配置深色模式主题
    • brightness 设置为 Brightness.dark
  2. 主题模式

    • themeMode: ThemeMode.system 跟随系统主题模式
    • 也可以设置为 ThemeMode.lightThemeMode.dark 强制使用浅色或深色模式
3.4 动态主题切换

在应用中实现动态主题切换功能:

class ThemeProvider extends ChangeNotifier {
  ThemeMode _themeMode = ThemeMode.system;

  ThemeMode get themeMode => _themeMode;

  void setThemeMode(ThemeMode mode) {
    _themeMode = mode;
    notifyListeners();
  }
}

代码解析:

  • 使用 ChangeNotifier 创建主题状态管理器
  • 提供 setThemeMode 方法切换主题模式
  • 通过 notifyListeners 通知所有监听者

四、鸿蒙色彩系统设计原理

4.1 色彩系统架构

鸿蒙设计语言的色彩系统采用以下架构:

┌──────────────────────────────────────────────────────────────┐
│                      色彩系统                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │   主色调    │  │   辅助色    │  │   中性色    │        │
│  │  Primary   │  │  Secondary │  │   Neutral  │        │
│  ├─────────────┤  ├─────────────┤  ├─────────────┤        │
│  │ #0A59F7    │  │ #00B42A    │  │ #1A1A1A    │        │
│  │ #4080FF    │  │ #FA5151    │  │ #434343    │        │
│  │ #69A0FF    │  │ #FA8C16    │  │ #666666    │        │
│  │ #93B5FF    │  │ #722ED1    │  │ #999999    │        │
│  │ #BED7FF    │  │ #13C2C2    │  │ #F5F7FA    │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└──────────────────────────────────────────────────────────────┘
4.2 色彩使用规范
颜色类型 使用场景 示例
主色调 品牌色、主要操作按钮、链接 按钮背景、选中状态
成功色 成功状态、在线状态、确认操作 勾选图标、成功提示
错误色 错误状态、离线状态、删除操作 错误提示、删除按钮
警告色 警告提示、待处理状态 警告图标、提醒信息
紫色 创意功能、特殊标记 高级功能入口
青色 科技感功能、创新特性 创新功能标识
深色中性色 主要文字、重要信息 标题、正文
浅色中性色 次要文字、辅助信息 描述文字、占位符
极浅色 背景色、分割线 页面背景、边框
4.3 色彩对比度

在使用颜色时,需要注意色彩对比度以确保可读性:

文本颜色 背景颜色 对比度 是否符合标准
#1A1A1A #FFFFFF 14.5:1
#1A1A1A #F5F7FA 13.1:1
#434343 #FFFFFF 7.4:1
#666666 #FFFFFF 4.5:1
#999999 #FFFFFF 2.8:1 ✗(仅用于次要信息)

五、主题适配最佳实践

5.1 使用 Theme.of 获取主题

在组件中使用 Theme.of(context) 获取主题数据:

Widget build(BuildContext context) {
  final theme = Theme.of(context);
  
  return Container(
    color: theme.colorScheme.background,
    child: Text(
      '示例文本',
      style: TextStyle(
        color: theme.colorScheme.onBackground,
        fontSize: theme.textTheme.bodyLarge?.fontSize,
      ),
    ),
  );
}

代码解析:

  • 使用 Theme.of(context) 获取当前主题
  • 使用 colorScheme 获取颜色配置
  • 使用 textTheme 获取字体配置
5.2 使用 ThemeData 扩展

创建自定义主题扩展以支持鸿蒙设计语言:

extension HarmonyOSThemeExtension on ThemeData {
  Color get harmonyPrimary => const Color(0xFF0A59F7);
  Color get harmonySuccess => const Color(0xFF00B42A);
  Color get harmonyError => const Color(0xFFFA5151);
  Color get harmonyWarning => const Color(0xFFFA8C16);
  
  TextStyle get harmonyTitle => TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.w600,
    color: const Color(0xFF1A1A1A),
  );
  
  TextStyle get harmonyBody => TextStyle(
    fontSize: 16,
    fontWeight: FontWeight.w400,
    color: const Color(0xFF1A1A1A),
  );
}

代码解析:

  • 使用扩展方法为 ThemeData 添加自定义属性
  • 方便在组件中直接调用
5.3 响应式主题

根据屏幕尺寸和设备类型调整主题:

ThemeData _buildTheme(BuildContext context) {
  final screenWidth = MediaQuery.of(context).size.width;
  
  if (screenWidth < 600) {
    return ThemeData(
      textTheme: TextTheme(
        bodyLarge: TextStyle(fontSize: 14),
        titleLarge: TextStyle(fontSize: 20),
      ),
    );
  } else {
    return ThemeData(
      textTheme: TextTheme(
        bodyLarge: TextStyle(fontSize: 16),
        titleLarge: TextStyle(fontSize: 24),
      ),
    );
  }
}

代码解析:

  • 根据屏幕宽度调整字体大小
  • 小屏幕使用较小字体,大屏幕使用较大字体

六、扩展知识

6.1 Material Design 3 配色系统

Material Design 3 引入了新的配色系统:

ColorScheme colorScheme = ColorScheme.fromSeed(
  seedColor: Colors.blue,
  brightness: Brightness.light,
);

// 主要颜色
colorScheme.primary;        // 主色
colorScheme.onPrimary;      // 主色上的文字颜色
colorScheme.primaryContainer; // 主色容器背景

// 次要颜色
colorScheme.secondary;      // 次要颜色
colorScheme.onSecondary;    // 次要颜色上的文字颜色

// 错误颜色
colorScheme.error;          // 错误颜色
colorScheme.onError;        // 错误颜色上的文字颜色

// 背景颜色
colorScheme.background;     // 背景色
colorScheme.onBackground;   // 背景上的文字颜色

// 表面颜色
colorScheme.surface;        // 表面色
colorScheme.onSurface;      // 表面上的文字颜色
6.2 颜色透明度计算

在 Flutter 中,可以使用 withValues 方法设置颜色透明度:

const Color primary = Color(0xFF0A59F7);

// 设置透明度为 50%
Color semiTransparent = primary.withValues(alpha: 0.5);

// 设置透明度为 10%
Color lightBackground = primary.withValues(alpha: 0.1);

透明度值说明:

  • alpha: 1.0:完全不透明
  • alpha: 0.5:半透明
  • alpha: 0.0:完全透明
6.3 主题切换动画

为主题切换添加动画效果:

AnimatedTheme(
  data: _isDark ? darkTheme : lightTheme,
  duration: Duration(milliseconds: 300),
  child: MyApp(),
);

代码解析:

  • 使用 AnimatedTheme 包裹应用根组件
  • 设置切换动画时长为 300ms
  • 主题切换时会有平滑的过渡效果
6.4 主题状态持久化

使用 SharedPreferences 持久化主题状态:

class ThemeService {
  static const String _themeKey = 'theme_mode';
  
  Future<ThemeMode> getThemeMode() async {
    final prefs = await SharedPreferences.getInstance();
    final mode = prefs.getString(_themeKey);
    
    switch (mode) {
      case 'light':
        return ThemeMode.light;
      case 'dark':
        return ThemeMode.dark;
      default:
        return ThemeMode.system;
    }
  }
  
  Future<void> setThemeMode(ThemeMode mode) async {
    final prefs = await SharedPreferences.getInstance();
    String modeString;
    
    switch (mode) {
      case ThemeMode.light:
        modeString = 'light';
        break;
      case ThemeMode.dark:
        modeString = 'dark';
        break;
      default:
        modeString = 'system';
    }
    
    await prefs.setString(_themeKey, modeString);
  }
}

代码解析:

  • 使用 SharedPreferences 存储主题模式
  • 提供 getThemeModesetThemeMode 方法
  • 支持 light、dark 和 system 三种模式

七、总结

本文详细讲解了「鸿蒙特性展示台」应用中设计语言页面的实现,包括:

  1. 色彩系统:主色调、辅助色、中性色的定义和展示
  2. 字体规范:9个层级的字体大小和粗细规范
  3. 组件样式:按钮、输入框、开关的鸿蒙风格实现
  4. 阴影层级:不同级别的阴影效果和圆角规范
  5. 主题配置:全局主题配置和深色模式支持

鸿蒙设计语言的色彩系统为应用提供了统一的视觉风格,通过合理使用主色调、辅助色和中性色,可以创建出符合鸿蒙生态的高质量应用界面。同时,支持深色模式和主题切换功能可以提升用户体验,满足不同用户的偏好需求。

Logo

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

更多推荐