【开源鸿蒙跨平台开发训练营】Flutter框架鸿蒙应用深色模式适配

为适应鸿蒙设备的深色模式,项目中加入多种风格模式的切换,增强用户体验

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

文章目录

鸿蒙系统(HarmonyOS)支持深色模式(Dark Mode),而Flutter作为跨平台框架,需通过适配确保应用在鸿蒙设备上能无缝切换深色与浅色主题。

功能实现 - 03:深色模式与外观切换

一、目标与方案

  • 目标:全应用适配深色模式,并在设置中提供外观切换(跟随系统 / 浅色 / 深色),选择结果持久化并在下次启动时生效。
  • 方案 :
    • 在 main.dart 中定义亮色、深色两套 ThemeData(Material 3 ColorScheme),通过 MaterialApp 的 theme、darkTheme、themeMode 驱动全局外观。
    • 使用 ValueNotifier<ThemeMode> 作为全局主题状态,与 SettingsService 持久化联动;设置页通过底部弹层选择模式并更新 Notifier,触发整应用重建。
    • 将各页中的硬编码颜色(如 Colors.grey[600])替换为 Theme.of(context).colorScheme 中的语义色,使列表、设置、发现、消息、收藏等页面在深色模式下自动呈现合适对比度。

二、依赖变更

  • 无新增依赖 。沿用现有 shared_preferences(SettingsService)与 Flutter 内置 ThemeData / ThemeMode。

三、实现说明

3.1 设置服务:主题模式持久化

文件 :lib/services/settings_service.dart

  • 新增存储键:_keyThemeMode = 'settings_theme_mode',取值:'light' / 'dark' / 'system'。
  • 新增方法:
    • Future<ThemeMode> getThemeMode():读取本地存储,默认 ThemeMode.system。
    • Future<void> setThemeMode(ThemeMode mode):写入并持久化。

3.2 应用入口:主题绑定与启动加载

文件 :lib/main.dart

  • 启动流程 :main() 改为 async,在 runApp 前调用 SettingsService().getThemeMode() 得到初始模式,并创建 appThemeModeNotifier = ValueNotifier<ThemeMode>(initialThemeMode)。
  • 主题定义 :
    • _lightTheme:ColorScheme.fromSeed(seedColor: Colors.deepPurple, brightness: Brightness.light),浅色背景与对比色。
    • _darkTheme:ColorScheme.fromSeed(..., brightness: Brightness.dark),深色表面色(如 #1C1B1F)与浅色前景。
  • MaterialApp :使用 ValueListenableBuilder<ThemeMode> 包裹,根据 appThemeModeNotifier 的当前值设置 themeMode,并同时传入 theme、darkTheme,实现即时切换且与系统深色模式解耦(当选择「跟随系统」时,Flutter 会按系统 brightness 自动选用 light/dark 主题)。

3.3 设置页:外观选项与模式选择

文件 :lib/pages/profile_page.dart

  • 在「设置」二级页的 ListView 顶部增加 「外观」 入口:
    • 标题:外观;副标题:当前模式文案(跟随系统 / 浅色 / 深色),通过 ValueListenableBuilder<ThemeMode> 与 appThemeModeNotifier 同步更新。
    • 点击后弹出 底部弹层 (showModalBottomSheet),内为三个 RadioListTile<ThemeMode>:跟随系统、浅色、深色。
  • 选择某一项后关闭弹层,若与当前模式不同则:
    • 更新 appThemeModeNotifier.value;
    • 调用 SettingsService().setThemeMode(chosen) 持久化。
  • 弹层内同样使用 ValueListenableBuilder<ThemeMode>,保证单选项与当前模式一致。

3.4 各页颜色适配主题

以下页面将原先的 Colors.grey[*]、固定黑白等替换为 Theme.of(context).colorScheme 的语义色,以便在深色模式下自动获得合适对比度:

文件 修改要点
root_page.dart 底部导航未选中色:Colors.grey → colorScheme.onSurfaceVariant
profile_page.dart 统计/菜单副标题、历史记录空状态与列表占位/副标题:Colors.grey[600]、Colors.grey[300] 等 → onSurfaceVariant、surfaceContainerHighest
search_page.dart 搜索框 hint/前缀图标、空状态图标与文案、卡片占位与作者/点赞文案:→ onSurfaceVariant、surfaceContainerHighest、surfaceContainerHigh
favorites_page.dart 空状态图标与文案、列表占位与副标题:→ onSurfaceVariant、surfaceContainerHighest
messages_page.dart 空状态、会话列表副标题与时间、输入栏阴影、发送按钮图标:→ onSurfaceVariant、colorScheme.shadow、onPrimary
privacy_settings_page.dart 隐私/用户协议/账号安全正文:Colors.grey[700] → onSurfaceVariant

未改动的部分(刻意保留):

  • 首页(home_page) 、作品详情(work_detail_page) 中全屏图片浏览区域使用黑色背景与白色叠加文字/控件,属于内容展示设计,不随浅/深主题切换,以保持沉浸式看图体验。
  • network_image_widget 等图片占位与叠加层仍使用深底浅字,与上述一致。

四、设置说明

  1. 打开应用 → 底部「我的」→ 右上角或列表中进入「设置」。
  2. 点击 「外观」 ,在底部弹层中选择:
    • 跟随系统:与系统深色/浅色设置一致;
    • 浅色:始终使用浅色主题;
    • 深色:始终使用深色主题。
  3. 选择后立即生效,且下次启动会保持上次选择。

五、修改了哪些文件?

文件 变更类型
lib/services/settings_service.dart 新增 getThemeMode / setThemeMode,引入 flutter/material.dart
lib/main.dart 异步启动、appThemeModeNotifier、亮/暗主题定义、ValueListenableBuilder + themeMode
lib/pages/profile_page.dart 设置页增加「外观」入口、底部弹层选择、_themeModeLabel / _showThemeModePicker;列表与历史页颜色改为 theme 语义色
lib/pages/root_page.dart 未选中色改为 onSurfaceVariant
lib/pages/search_page.dart 搜索框、空状态、卡片内文案与占位改为 theme 语义色
lib/pages/favorites_page.dart 空状态与列表占位/副标题改为 theme 语义色
lib/pages/messages_page.dart 空状态、列表副标题/时间、输入区阴影、发送图标改为 theme 语义色
lib/pages/privacy_settings_page.dart 正文颜色改为 onSurfaceVariant

六、测试建议

  • 在设置中依次切换「跟随系统」「浅色」「深色」,确认各 Tab(首页、发现、消息、我的)及二级页(设置、隐私、收藏、历史、搜索列表等)背景与文字对比度正常。
  • 切换为深色后杀进程再启动,确认仍为深色;同理验证浅色与跟随系统。
  • 在系统设置中切换深色/浅色,仅当应用内为「跟随系统」时应用外观应随之变化。
结束语

感谢阅读本帖,如对贴中内容有意见和建议的,欢迎与我联系交流,也欢迎加入开源鸿蒙跨平台社区:

https://openharmonycrossplatform.csdn.net

相关推荐
梦想不只是梦与想1 小时前
鸿蒙 预览数据模拟:Hamock
harmonyos·模拟数据·hamock
FungLeo2 小时前
成为全栈·Flutter App 篇·第四批复盘:复用了什么,移动端又新增了什么
flutter·移动开发·跨端开发·成为全栈·api契约·全栈复盘
jason.zeng@15022074 小时前
使用vscode+flutter开发android程序(入门)
android·vscode·flutter
贾伟康4 小时前
【化学实验室|04】HarmonyOS ArkTS 场景选择器实战:让 13 个离线实验的入口、筛选和返回路径保持一致
harmonyos·arkts·canvas·arkui·化学实验
jason.zeng@15022074 小时前
Flutter 项目标准分层目录(repository/dto/page,对齐后端思想)
flutter
特立独行的猫a4 小时前
仓颉语言GUI开发实战:用仓颉写串口/网络二合一调试助手
网络·ui·gui·harmonyos·tauri·仓颉
hqzing14 小时前
把 glibc 移植到鸿蒙 PC 上:它能用来做什么
华为·harmonyos
OH_TPC20 小时前
HarmonyOS APP开发---“习惯猫“习惯打卡App,需要用到这个库
华为·harmonyos·鸿蒙
熊猫钓鱼>_>1 天前
开源鸿蒙平台 KMP 三方库 kotlin-csv 适配全流程:从编码假设到沙箱真机互通验证
开发语言·人工智能·华为·kotlin·harmonyos·鸿蒙
马剑威(威哥爱编程)1 天前
【共创稿事节】HarmonyOS 7 Agent 开发实战 09:Agent 测试评测集
华为·harmonyos