开源鸿蒙 Flutter 实战|深色模式切换保姆级教程(鸿蒙兼容 + 可直接运行)
🎨 开源鸿蒙 Flutter 实战|深色模式切换保姆级教程(鸿蒙兼容 + 可直接运行)
欢迎加入开源鸿蒙跨平台社https://openharmonycrosplatform.csdn.net
哈喽宝子们!我是刚学跨平台开发的大一新生😆 这次给我的鸿蒙 FlutterAPP 加上了深色模式切换功能,不仅能一键切换浅色 / 深色主题,还能自动保存主题偏好,下次打开 APP 自动恢复,体验超丝滑!
全程用的都是OpenHarmony 官方兼容清单里的库,完全没有兼容问题,新手也能直接抄作业!
先给大家汇报一下这次的成果✨
✅ 深色 / 浅色主题一键切换
✅ 主题偏好本地持久化保存
✅ 切换时丝滑过渡动画
✅ 鸿蒙虚拟机实机验证,无闪退卡顿
✅ 代码极简,新手友好度拉满
一、用到的鸿蒙兼容库
选库的时候我特意翻了 OpenHarmony 官方的三方库兼容清单,就怕选到不兼容的库踩坑,最终选了两个对新手极度友好、鸿蒙适配拉满的库:
直接在pubspec.yaml里加上依赖,执行flutter pub get就能用啦:
name: flutter_hm_dark_mode_demo
description: 开源鸿蒙Flutter深色模式实战项目
version: 1.0.0+1
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
dio: ^5.4.0
flutter_animate: ^4.5.0
animations: ^2.0.11
# 核心库:状态管理+本地存储 鸿蒙完美适配
provider: ^6.1.1
shared_preferences: ^2.3.2
flutter:
uses-material-design: true
二、核心功能实现
2.1 第一步:创建主题管理 Provider
用 provider 来管理主题状态,是 Flutter 官方推荐的轻量级状态管理方案,代码超简单,新手也能看懂。
在lib目录下新建providers文件夹,创建theme_provider.dart文件:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// 主题管理Provider 鸿蒙适配版
class ThemeProvider extends ChangeNotifier {
// 本地存储的key
static const String _themeKey = 'is_dark_mode';
// SharedPreferences实例
late SharedPreferences _prefs;
// 当前主题模式:false=浅色,true=深色
bool _isDarkMode = false;
bool get isDarkMode => _isDarkMode;
/// 初始化:从本地读取保存的主题偏好
Future<void> init() async {
_prefs = await SharedPreferences.getInstance();
// 读取本地存储的主题,默认浅色模式
_isDarkMode = _prefs.getBool(_themeKey) ?? false;
notifyListeners();
}
/// 切换主题
void toggleTheme() {
_isDarkMode = !_isDarkMode;
// 保存到本地
_prefs.setBool(_themeKey, _isDarkMode);
// 通知UI更新
notifyListeners();
}
/// 获取当前主题数据
ThemeData get currentTheme {
return _isDarkMode ? darkTheme : lightTheme;
}
/// 浅色主题配置
static final ThemeData lightTheme = ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.purple,
scaffoldBackgroundColor: Colors.white,
cardColor: Colors.white,
textTheme: const TextTheme(
bodyLarge: TextStyle(color: Colors.black87),
bodyMedium: TextStyle(color: Colors.black54),
),
appBarTheme: const AppBarTheme(
backgroundColor: Colors.purple,
foregroundColor: Colors.white,
elevation: 0,
),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
selectedItemColor: Colors.purple,
unselectedItemColor: Colors.grey,
backgroundColor: Colors.white,
),
);
/// 深色主题配置
static final ThemeData darkTheme = ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.purple,
scaffoldBackgroundColor: const Color(0xFF121212), // Material标准深色背景
cardColor: const Color(0xFF1E1E1E),
textTheme: const TextTheme(
bodyLarge: TextStyle(color: Colors.white),
bodyMedium: TextStyle(color: Colors.white70),
),
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF1E1E1E),
foregroundColor: Colors.white,
elevation: 0,
),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
selectedItemColor: Colors.purple,
unselectedItemColor: Colors.grey,
backgroundColor: Color(0xFF1E1E1E),
),
);
}
2.3 第三步:在 “我的” 页面添加主题切换开关
修改lib/pages/mine_page.dart,添加主题切换卡片,用 Switch 组件实现一键切换,同时加上丝滑的动画效果:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/theme_provider.dart';
class MinePage extends StatelessWidget {
const MinePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("个人中心"), centerTitle: true),
body: ListView(
children: [
// 用户信息区域
Container(
padding: const EdgeInsets.all(20),
child: const Row(
children: [
CircleAvatar(radius: 35, backgroundImage: NetworkImage("https://picsum.photos/200")),
SizedBox(width: 16),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("鸿蒙开发者", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
Text("计算机大一新生 | 跨平台开发", style: TextStyle(color: Colors.grey)),
],
),
],
),
),
const SizedBox(height: 10),
// 主题切换卡片
Consumer<ThemeProvider>(
builder: (context, themeProvider, child) {
return Card(
margin: const EdgeInsets.symmetric(horizontal: 12),
child: ListTile(
leading: Icon(
themeProvider.isDarkMode ? Icons.dark_mode : Icons.light_mode,
color: Theme.of(context).primaryColor,
),
title: const Text("外观模式"),
subtitle: Text(themeProvider.isDarkMode ? "深色模式" : "浅色模式"),
trailing: Switch(
value: themeProvider.isDarkMode,
onChanged: (value) {
// 切换主题
themeProvider.toggleTheme();
},
activeColor: Theme.of(context).primaryColor,
),
),
);
},
),
const SizedBox(height: 10),
// 其他功能菜单
const ListTile(leading: Icon(Icons.star), title: Text("我的收藏")),
const ListTile(leading: Icon(Icons.history), title: Text("浏览历史")),
const ListTile(leading: Icon(Icons.thumb_up), title: Text("我的点赞")),
const ListTile(leading: Icon(Icons.settings), title: Text("设置中心")),
const ListTile(leading: Icon(Icons.help), title: Text("帮助反馈")),
],
),
);
}
}
三、鸿蒙适配核心要点
作为新手,这次实现深色模式也踩了好几个鸿蒙专属的小坑,整理出来给大家避避坑:
1.版本选择:必须用稳定版,provider 6.1.1、shared_preferences 2.3.2,Flutter SDK 3.16 + 鸿蒙适配版,低版本会出现本地存储读取失败的问题
2.初始化时机:必须在main函数中先调用WidgetsFlutterBinding.ensureInitialized(),再初始化 SharedPreferences,否则会在鸿蒙设备上出现初始化异常
3.深色主题配色:推荐使用 Material 标准的深色背景色0xFF121212,卡片色0xFF1E1E1E,在鸿蒙设备上显示效果最好,不会出现过暗或过亮的问题
4.权限说明:shared_preferences 是纯本地存储,不需要在鸿蒙里申请任何额外权限,仅需保留之前的网络权限就完全够用
5.主题切换动画:Flutter 官方的themeAnimationDuration和themeAnimationCurve在鸿蒙设备上完美支持,不需要自己做额外适配
四、鸿蒙虚拟机运行验证
一键运行命令
cd ohos
hvigorw assembleHap -p product=default -p buildMode=debug
hdc install -r entry/build/default/outputs/default/entry-default-unsigned.hap
hdc shell aa start -a EntryAbility -b com.example.demo1
虚拟机运行效果展示
五、新手总结与后续拓展
作为刚学 Flutter 和鸿蒙开发的大一新生,这次深色模式切换功能的实现真的让我超有成就感!原来只需要用 provider 和 shared_preferences 两个简单的库,就能实现这么实用的功能,而且全程没有遇到太复杂的兼容问题,开源鸿蒙的生态对新手也越来越友好了🥰
当然我还有很多要学习的地方,这次的深色模式只是基础实现,后续我还会研究:
1.跟随系统深色模式自动切换
2.自定义主题色切换
3.深色模式下的图片适配
4.更多鸿蒙原生能力的接入与适配
也会持续给大家分享我的新手实战内容,和大家一起在开源鸿蒙的生态里慢慢进步✨
如果这篇文章有帮到你,或者你也有新手开发的小技巧,欢迎在评论区和我交流呀!
更多推荐


所有评论(0)