欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

本文是我参考其他人的文章后的实践

参考文章链接在这:

https://blog.csdn.net/2301_80035882/article/details/155376457?fromshare=blogdetail&sharetype=blogdetail&sharerId=155376457&sharerefer=PC&sharesource=jhp0108&sharefrom=from_link

前言

本文为 Flutter for OpenHarmony 系列开发笔记第十一篇,基于 Material Design 3 设计规范,为 AtomGit 口袋工具实现深色模式适配功能,支持跟随 OpenHarmony/Windows 系统的深色模式设置,实现亮 / 暗主题自动切换,同时统一管理全局主题样式,确保所有页面风格一致,适配过程采用 Flutter 官方推荐的 ColorScheme 主题方案,适合学习跨平台应用的主题适配开发。

一、深色模式适配背景
  1. 用户需求:深色模式可降低夜间使用的视觉疲劳,是现代应用的标配功能;
  2. 平台适配:OpenHarmony 系统支持全局深色模式设置,应用需跟随系统设置实现自动切换;
  3. 原项目问题:AtomGit 口袋工具仅支持浅色模式,无深色主题,夜间使用体验差;
  4. 设计规范:采用 Material Design 3(M3)规范,实现现代化、一致性的亮 / 暗主题效果。
二、适配核心原理
  1. 主题管理:创建全局主题管理类AppTheme,统一定义浅色 / 深色主题的样式规则;
  2. 颜色体系:基于ColorScheme.fromSeed实现种子色配色,确保亮 / 暗主题的颜色协调性;
  3. 跟随系统:通过ThemeMode.system让应用跟随操作系统的深色模式设置,实现自动切换;
  4. 全局统一:所有页面的样式均基于主题色配置,避免硬编码颜色,确保主题切换时全局生效。
三、前置准备:将华为模拟器调为深色模式
  1. 启动 DevEco Studio 中的华为模拟器(如 Mate 70 Pro);
  2. 从模拟器屏幕顶部向下滑动,打开控制中心
  3. 找到深色模式开关,点击开启,模拟器界面切换为深色模式(关闭则切回浅色模式);
  4. 本次适配实现应用跟随系统,修改系统深色模式设置,应用会自动同步切换。

四、适配步骤一:创建全局主题管理文件
4.1 新建文件

在项目中新建路径lib/core,创建app_theme.dart文件,用于统一管理浅色 / 深色主题的所有配置。

4.2 主题核心代码(Material3 + ColorScheme)
import 'package:flutter/material.dart';

/// 全局主题管理类,统一管理浅色/深色主题,适配OpenHarmony系统夜间模式
/// 基于Material Design 3规范,使用ColorScheme种子色配色
class AppTheme {
  // 私有构造方法,禁止实例化
  AppTheme._();

  // 主题种子色(Indigo靛蓝色,Material3推荐色,可根据需求修改)
  static const Color _seedColor = Colors.indigo;

  // 浅色主题
  static ThemeData light() => _theme(Brightness.light);

  // 深色主题
  static ThemeData dark() => _theme(Brightness.dark);

  // 通用主题构建方法,根据Brightness生成对应主题
  static ThemeData _theme(Brightness brightness) {
    // 根据种子色和亮度生成ColorScheme,自动协调所有颜色值
    final colorScheme = ColorScheme.fromSeed(
      seedColor: _seedColor,
      brightness: brightness,
    );
    // 判断是否为深色模式
    final isDark = brightness == Brightness.dark;

    return ThemeData(
      // 配置ColorScheme颜色体系
      colorScheme: colorScheme,
      // 启用Material Design 3
      useMaterial3: true,
      // 视觉密度,适配不同设备
      visualDensity: VisualDensity.standard,
      // 主题亮度
      brightness: brightness,
      // 页面背景色,使用ColorScheme的surface色
      scaffoldBackgroundColor: colorScheme.surface,

      // AppBar主题配置
      appBarTheme: AppBarTheme(
        backgroundColor: colorScheme.surface,
        foregroundColor: colorScheme.onSurface,
        centerTitle: true,
        elevation: 0, // 取消阴影,扁平化设计
      ),

      // 底部导航栏主题配置
      navigationBarTheme: NavigationBarThemeData(
        backgroundColor: colorScheme.surfaceContainerHigh,
        // 导航栏选中项指示器颜色,深色/浅色模式不同透明度
        indicatorColor: colorScheme.primary.withValues(alpha: isDark ? 0.35 : 0.2),
        labelBehavior: NavigationDestinationLabelBehavior.alwaysShow, // 始终显示标签
      ),

      // 卡片组件主题配置
      cardTheme: CardTheme(
        color: colorScheme.surfaceContainerLowest,
        elevation: 0,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20), // 圆角设计
        ),
      ),

      // 输入框主题配置
      inputDecorationTheme: InputDecorationTheme(
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(16),
          borderSide: BorderSide(color: colorScheme.outlineVariant),
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(16),
          borderSide: BorderSide(color: colorScheme.outlineVariant),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(16),
          borderSide: BorderSide(color: colorScheme.primary, width: 1.4),
        ),
        filled: true,
        fillColor: colorScheme.surfaceContainerLowest,
        labelStyle: TextStyle(color: colorScheme.onSurfaceVariant),
        hintStyle: TextStyle(
          color: colorScheme.onSurfaceVariant.withValues(alpha: 0.7),
        ),
        prefixIconColor: colorScheme.onSurfaceVariant,
      ),

      // 标签组件主题配置
      chipTheme: ChipThemeData(
        backgroundColor: colorScheme.surfaceContainerHigh,
        selectedColor: colorScheme.primary.withValues(alpha: 0.2),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(24),
        ),
        labelStyle: TextStyle(color: colorScheme.onSurface),
      ),

      // 分割线主题配置
      dividerTheme: DividerThemeData(
        color: colorScheme.outlineVariant.withValues(alpha: 0.7),
        thickness: 1,
      ),
    );
  }
}
4.3 代码核心解析
  1. 种子色配色:通过ColorScheme.fromSeed传入种子色(Colors.indigo),Flutter 会自动生成协调的亮 / 暗主题颜色体系,无需手动定义每个颜色;
  2. Material3 启用:设置useMaterial3: true,遵循最新的 Material Design 3 设计规范;
  3. 全局样式统一:对 AppBar、导航栏、卡片、输入框等所有核心组件进行主题配置,确保全局样式一致;
  4. 深色 / 浅色差异化:通过isDark判断主题模式,对指示器透明度等细节进行差异化配置,提升体验。
五、适配步骤二:修改项目入口,配置主题并跟随系统
5.1 修改 main.dart 文件

打开项目入口文件lib/main.dart,找到MaterialApp组件,修改为以下代码,配置亮 / 暗主题并设置跟随系统:

import 'package:flutter/material.dart';
// 导入全局主题管理类(必须添加,否则报错)
import 'package:gitcode_pocket_tool/core/app_theme.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GitCode 口袋工具',
      theme: AppTheme.light(), // 配置浅色主题
      darkTheme: AppTheme.dark(), // 配置深色主题
      themeMode: ThemeMode.system, // 关键:跟随系统的深色模式设置
      home: const MainNavigationPage(),
      debugShowCheckedModeBanner: false, // 隐藏调试横幅
    );
  }
}
5.2 核心配置说明
  1. theme: AppTheme.light():设置应用的浅色主题;
  2. darkTheme: AppTheme.dark():设置应用的深色主题;
  3. themeMode: ThemeMode.system核心配置,让应用跟随操作系统(OpenHarmony/Windows)的深色模式设置,实现自动切换;
    • 可选值:ThemeMode.light(强制浅色)、ThemeMode.dark(强制深色)、ThemeMode.system(跟随系统)。
六、适配步骤三:优化错误提示组件,适配深色模式
6.1 优化场景

原项目中搜索页面的错误提示横幅(_InfoBanner)硬编码了颜色,深色模式下显示效果差,需修改为基于主题色的动态颜色。

6.2 实现代码(路径:lib/pages/search_page.dart)
// 错误提示横幅,使用主题色的errorContainer和onErrorContainer,适配深色模式
return _InfoBanner(
  icon: Icons.error_outline,
  background: scheme.errorContainer, // 动态错误背景色
  textColor: scheme.onErrorContainer, // 动态错误文字色
  message: _errorMessage!,
);
6.3 优化原理

使用ColorScheme中的errorContainer(错误背景色)和onErrorContainer(错误文字色),这两个颜色会根据主题模式(亮 / 暗)自动切换,确保错误提示在浅色 / 深色模式下都有良好的对比度和显示效果。

七、运行测试:验证深色模式适配效果
  1. 确保所有代码修改后已保存,执行flutter pub get更新依赖;
  2. 启动 DevEco Studio 模拟器,先将系统设置为浅色模式,运行 AtomGit 口袋工具,验证浅色主题显示正常;
  3. 打开模拟器控制中心,开启深色模式,应用会自动切换为深色主题,所有页面(首页 / 搜索 / 我的)同步更新;
  4. 验证所有组件的显示效果:AppBar、导航栏、输入框、卡片、错误提示等均需适配深色模式,无样式错乱、颜色对比度过低等问题。
八、深色模式适配效果演示
8.1 浅色模式效果
  • 页面背景:浅白色,文字为深灰色;
  • 组件颜色:基于 Indigo 种子色的浅色调,按钮 / 指示器为淡蓝色;
  • 输入框:浅灰色背景,边框为淡灰色,聚焦时为 Indigo 主色。
8.2 深色模式效果
  • 页面背景:深灰色,文字为浅白色;
  • 组件颜色:基于 Indigo 种子色的深色调,按钮 / 指示器为深蓝色(低透明度);
  • 输入框:深灰色背景,边框为深灰色,聚焦时为 Indigo 主色;
  • 所有组件的颜色对比度符合 Material Design 3 规范,无视觉疲劳。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐