1. 项目背景与核心价值
最近在OpenHarmony生态中尝试用Flutter开发了一款家具购买记录应用,其中提醒列表功能是这款工具的核心模块。这个功能看似简单,但在实际开发中涉及到状态管理、本地存储、跨平台UI适配等多个技术难点。作为同时接触过原生HarmonyOS和Flutter的开发者,我发现Flutter for OpenHarmony这个组合在开发效率上有独特优势。
这个家具购买记录App主要解决三个实际问题:
- 帮助用户记录需要购买的家具清单
- 设置购买提醒时间(如促销季、搬家前等)
- 按照优先级和分类管理待购物品
2. 技术选型与架构设计
2.1 为什么选择Flutter for OpenHarmony
在OpenHarmony上使用Flutter主要基于以下考虑:
- 开发效率:一套代码可以同时适配手机、平板等多种OpenHarmony设备
- UI一致性:Flutter的widget系统能保证在不同设备上呈现相同的视觉效果
- 热重载:开发过程中可以快速看到修改效果,特别适合UI密集型的应用
2.2 应用架构设计
采用典型的MVVM架构:
- Model层:使用Hive进行本地数据存储 - ViewModel层:Riverpod管理状态 - View层:Flutter Widget构建UI提示:在OpenHarmony环境下,需要特别注意Hive的存储路径适配,后面会详细说明具体配置方法。
3. 提醒列表核心实现
3.1 数据结构设计
首先定义提醒项的数据模型:
@HiveType(typeId: 0) class FurnitureReminder { @HiveField(0) final String name; @HiveField(1) final DateTime remindTime; @HiveField(2) final int priority; // 1-5级 @HiveField(3) final String category; // 其他字段... }3.2 本地存储方案
在OpenHarmony上使用Hive需要特殊配置:
- 修改默认存储路径:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // OpenHarmony适配 final appDocDir = await getApplicationDocumentsDirectory(); Hive.init(appDocDir.path); // 注册适配器 Hive.registerAdapter(FurnitureReminderAdapter()); runApp(const MyApp()); }- 初始化Box:
final reminderBox = await Hive.openBox<FurnitureReminder>('reminders');3.3 列表UI实现
使用ListView.builder构建高性能列表:
ListView.builder( itemCount: reminders.length, itemBuilder: (context, index) { final reminder = reminders[index]; return Dismissible( key: Key(reminder.id), background: Container(color: Colors.red), onDismissed: (direction) { // 删除逻辑 }, child: ListTile( leading: _buildPriorityIcon(reminder.priority), title: Text(reminder.name), subtitle: Text( DateFormat('yyyy-MM-dd').format(reminder.remindTime), ), trailing: IconButton( icon: const Icon(Icons.notifications_active), onPressed: () => _showReminderDialog(reminder), ), ), ); }, )4. 提醒功能实现细节
4.1 定时提醒实现
使用flutter_local_notifications插件:
dependencies: flutter_local_notifications: ^9.7.0初始化配置:
final FlutterLocalNotificationsPlugin notificationsPlugin = FlutterLocalNotificationsPlugin(); const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('app_icon'); final InitializationSettings initializationSettings = InitializationSettings( android: initializationSettingsAndroid, ); await notificationsPlugin.initialize( initializationSettings, onDidReceiveNotificationResponse: _onNotificationTap, );设置提醒:
Future<void> scheduleReminder(FurnitureReminder reminder) async { await notificationsPlugin.zonedSchedule( reminder.hashCode, '家具购买提醒', '您有${reminder.name}需要购买', tz.TZDateTime.from(reminder.remindTime, tz.local), const NotificationDetails( android: AndroidNotificationDetails( 'furniture_channel', '家具提醒', importance: Importance.max, priority: Priority.high, ), ), androidAllowWhileIdle: true, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, ); }4.2 状态管理方案
使用Riverpod管理全局状态:
final remindersProvider = StateNotifierProvider<RemindersNotifier, List<FurnitureReminder>>((ref) { return RemindersNotifier(); }); class RemindersNotifier extends StateNotifier<List<FurnitureReminder>> { RemindersNotifier() : super([]); void addReminder(FurnitureReminder reminder) { state = [...state, reminder]; reminderBox.add(reminder); scheduleReminder(reminder); } // 其他操作方法... }5. OpenHarmony适配要点
5.1 平台特性适配
- 权限处理:
// 检查通知权限 final status = await notificationsPlugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.areNotificationsEnabled(); if (status == false) { // 引导用户开启权限 }- 后台任务: 在OpenHarmony上需要配置后台服务保持提醒触发:
void main() { // 初始化后台任务 Workmanager().initialize( callbackDispatcher, isInDebugMode: true, ); // 设置周期性任务检查提醒 Workmanager().registerPeriodicTask( "reminder-check", "reminderCheckTask", frequency: const Duration(hours: 12), ); }5.2 性能优化技巧
- 列表性能优化:
ListView.builder( // 添加以下参数优化长列表 addAutomaticKeepAlives: true, addRepaintBoundaries: true, addSemanticIndexes: true, // ... );- 图片缓存优化:
CachedNetworkImage( imageUrl: furnitureItem.imageUrl, placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => Icon(Icons.error), );6. 常见问题与解决方案
6.1 通知不触发问题排查
- 检查Doze模式设置:
adb shell dumpsys deviceidle whitelist +com.example.app- 验证通知渠道配置:
// 创建高优先级通知渠道 const AndroidNotificationChannel channel = AndroidNotificationChannel( 'high_importance_channel', '重要提醒', importance: Importance.max, ); await notificationsPlugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel);6.2 数据同步问题
使用Hive时可能遇到的数据同步问题解决方案:
- 确保所有写操作都在transaction中:
await reminderBox.transaction(() async { await reminderBox.put(key, value); });- 添加异常处理:
try { await Hive.openBox('reminders'); } on HiveError catch (e) { // 处理损坏的box await Hive.deleteBoxFromDisk('reminders'); await Hive.openBox('reminders'); }7. 界面优化技巧
7.1 动画效果增强
添加列表项动画:
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; AnimationLimiter( child: ListView.builder( itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 375), child: SlideAnimation( verticalOffset: 50.0, child: FadeInAnimation( child: YourListItemWidget(), ), ), ); }, ), );7.2 主题适配
实现深色模式支持:
MaterialApp( theme: ThemeData.light(), darkTheme: ThemeData.dark(), themeMode: context.watch<ThemeProvider>().themeMode, // ... );8. 测试策略
8.1 单元测试示例
测试提醒逻辑:
test('should schedule notification when reminder is added', () async { // 初始化 final container = ProviderContainer(); addTearDown(container.dispose); // 准备测试数据 final testReminder = FurnitureReminder( name: '测试椅子', remindTime: DateTime.now().add(Duration(minutes: 5)), priority: 3, category: '客厅', ); // 执行操作 container.read(remindersProvider.notifier).addReminder(testReminder); // 验证结果 expect(container.read(remindersProvider).length, 1); expect( container.read(remindersProvider).first.name, equals('测试椅子'), ); });8.2 集成测试要点
测试完整流程:
void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('添加提醒完整流程测试', (WidgetTester tester) async { // 启动应用 await tester.pumpWidget(ProviderScope(child: MyApp())); // 点击添加按钮 await tester.tap(find.byIcon(Icons.add)); await tester.pumpAndSettle(); // 填写表单 await tester.enterText(find.byType(TextField).first, '新沙发'); // ...其他表单字段 // 提交表单 await tester.tap(find.text('保存')); await tester.pumpAndSettle(); // 验证结果 expect(find.text('新沙发'), findsOneWidget); }); }9. 发布准备
9.1 OpenHarmony应用配置
在config.json中添加必要权限:
{ "abilities": [ { "name": "MainAbility", "permissions": [ "ohos.permission.NOTIFICATION_CONTROLLER", "ohos.permission.KEEP_BACKGROUND_RUNNING" ] } ] }9.2 构建发布版本
Flutter构建命令:
flutter build ohos --release10. 扩展功能思路
- 云端同步:接入OpenHarmony的分布式数据服务,实现多设备同步
- AR预览:使用ARKit/ARCore让用户预览家具在房间的效果
- 比价功能:接入电商API自动比价
- 预算管理:添加预算跟踪和超支提醒
在实际开发过程中,我发现Flutter在OpenHarmony上的表现相当稳定,特别是热重载功能大大提升了开发效率。对于需要快速开发跨OpenHarmony设备应用的情况,Flutter是一个值得考虑的选择。