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

四、适配步骤一:创建全局主题管理文件
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 代码核心解析
- 种子色配色:通过
ColorScheme.fromSeed传入种子色(Colors.indigo),Flutter 会自动生成协调的亮 / 暗主题颜色体系,无需手动定义每个颜色; - Material3 启用:设置
useMaterial3: true,遵循最新的 Material Design 3 设计规范; - 全局样式统一:对 AppBar、导航栏、卡片、输入框等所有核心组件进行主题配置,确保全局样式一致;
- 深色 / 浅色差异化:通过
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 核心配置说明
theme: AppTheme.light():设置应用的浅色主题;darkTheme: AppTheme.dark():设置应用的深色主题;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(错误文字色),这两个颜色会根据主题模式(亮 / 暗)自动切换,确保错误提示在浅色 / 深色模式下都有良好的对比度和显示效果。
七、运行测试:验证深色模式适配效果
- 确保所有代码修改后已保存,执行
flutter pub get更新依赖; - 启动 DevEco Studio 模拟器,先将系统设置为浅色模式,运行 AtomGit 口袋工具,验证浅色主题显示正常;
- 打开模拟器控制中心,开启深色模式,应用会自动切换为深色主题,所有页面(首页 / 搜索 / 我的)同步更新;
- 验证所有组件的显示效果:AppBar、导航栏、输入框、卡片、错误提示等均需适配深色模式,无样式错乱、颜色对比度过低等问题。
八、深色模式适配效果演示
8.1 浅色模式效果
- 页面背景:浅白色,文字为深灰色;
- 组件颜色:基于 Indigo 种子色的浅色调,按钮 / 指示器为淡蓝色;
- 输入框:浅灰色背景,边框为淡灰色,聚焦时为 Indigo 主色。
8.2 深色模式效果
- 页面背景:深灰色,文字为浅白色;
- 组件颜色:基于 Indigo 种子色的深色调,按钮 / 指示器为深蓝色(低透明度);
- 输入框:深灰色背景,边框为深灰色,聚焦时为 Indigo 主色;
- 所有组件的颜色对比度符合 Material Design 3 规范,无视觉疲劳。

更多推荐
所有评论(0)