ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Flutter在OpenHarmony上的家具提醒应用开发实践

Flutter在OpenHarmony上的家具提醒应用开发实践

1. 项目背景与核心价值

最近在OpenHarmony生态中尝试用Flutter开发了一款家具购买记录应用,其中提醒列表功能是这款工具的核心模块。这个功能看似简单,但在实际开发中涉及到状态管理、本地存储、跨平台UI适配等多个技术难点。作为同时接触过原生HarmonyOS和Flutter的开发者,我发现Flutter for OpenHarmony这个组合在开发效率上有独特优势。

这个家具购买记录App主要解决三个实际问题:

  1. 帮助用户记录需要购买的家具清单
  2. 设置购买提醒时间(如促销季、搬家前等)
  3. 按照优先级和分类管理待购物品

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需要特殊配置:

  1. 修改默认存储路径:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // OpenHarmony适配 final appDocDir = await getApplicationDocumentsDirectory(); Hive.init(appDocDir.path); // 注册适配器 Hive.registerAdapter(FurnitureReminderAdapter()); runApp(const MyApp()); }
  1. 初始化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 平台特性适配

  1. 权限处理:
// 检查通知权限 final status = await notificationsPlugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.areNotificationsEnabled(); if (status == false) { // 引导用户开启权限 }
  1. 后台任务: 在OpenHarmony上需要配置后台服务保持提醒触发:
void main() { // 初始化后台任务 Workmanager().initialize( callbackDispatcher, isInDebugMode: true, ); // 设置周期性任务检查提醒 Workmanager().registerPeriodicTask( "reminder-check", "reminderCheckTask", frequency: const Duration(hours: 12), ); }

5.2 性能优化技巧

  1. 列表性能优化:
ListView.builder( // 添加以下参数优化长列表 addAutomaticKeepAlives: true, addRepaintBoundaries: true, addSemanticIndexes: true, // ... );
  1. 图片缓存优化:
CachedNetworkImage( imageUrl: furnitureItem.imageUrl, placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => Icon(Icons.error), );

6. 常见问题与解决方案

6.1 通知不触发问题排查

  1. 检查Doze模式设置:
adb shell dumpsys deviceidle whitelist +com.example.app
  1. 验证通知渠道配置:
// 创建高优先级通知渠道 const AndroidNotificationChannel channel = AndroidNotificationChannel( 'high_importance_channel', '重要提醒', importance: Importance.max, ); await notificationsPlugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel);

6.2 数据同步问题

使用Hive时可能遇到的数据同步问题解决方案:

  1. 确保所有写操作都在transaction中:
await reminderBox.transaction(() async { await reminderBox.put(key, value); });
  1. 添加异常处理:
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 --release

10. 扩展功能思路

  1. 云端同步:接入OpenHarmony的分布式数据服务,实现多设备同步
  2. AR预览:使用ARKit/ARCore让用户预览家具在房间的效果
  3. 比价功能:接入电商API自动比价
  4. 预算管理:添加预算跟踪和超支提醒

在实际开发过程中,我发现Flutter在OpenHarmony上的表现相当稳定,特别是热重载功能大大提升了开发效率。对于需要快速开发跨OpenHarmony设备应用的情况,Flutter是一个值得考虑的选择。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进