作为一名长期从事Flutter开发的工程师,我发现物品收纳管理是很多家庭的实际需求。这次我将分享如何用Flutter框架开发一个同时支持鸿蒙系统的居家收纳应用,这个项目已经在我们团队内部使用了半年多,效果出乎意料的好。
这个应用最核心的价值在于:通过双维度分类(房间+物品类别)和智能搜索,能让你在3秒内找到任何物品的精确位置。我家的物品寻找时间从平均15分钟降到了几乎可以忽略不计,特别是当家里老人帮忙整理后经常忘记物品位置时,这个应用简直就是救星。
在技术选型阶段,我们对比了多种方案:
实测数据表明,Flutter在鸿蒙设备上的性能表现:
特别值得一提的是,Flutter for HarmonyOS的插件生态已经相当完善,我们需要的相机、二维码、本地存储等功能都有现成可用的插件。
我们采用典型的MVVM架构:
code复制┌───────────────────────────────────────┐
│ UI层 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 页面组件 │ │ 通用组件 │ │
│ └─────────────┘ └─────────────┘ │
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ 业务逻辑层 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ ViewModel │ │ 服务层 │ │
│ └─────────────┘ └─────────────┘ │
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ 数据持久层 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 本地数据库 │ │ 网络同步 │ │
│ └─────────────┘ └─────────────┘ │
└───────────────────────────────────────┘
物品分类我们使用了Dart的增强枚举,这是实际开发中非常实用的特性:
dart复制enum ItemCategory {
clothing('衣物', Icons.checkroom, Color(0xFF42A5F5)),
electronics('电子产品', Icons.devices, Color(0xFF66BB6A)),
// ...其他分类
final String label;
final IconData icon;
final Color themeColor;
const ItemCategory(this.label, this.icon, this.themeColor);
}
数据库模型设计有几个关键点需要注意:
这是我们优化后的StorageItem模型:
dart复制class StorageItem {
final String id;
final String name;
final ItemCategory category;
final String locationId;
final int quantity;
final String? barcode; // 新增字段:物品条形码
final String note;
final DateTime addedDate;
bool isFavorite;
DateTime? expiryDate; // 新增字段:过期日期
// 添加fromJson/toJson方法以支持序列化
// 添加copyWith方法以支持状态更新
}
房间筛选功能我们采用了分段控件实现,这是优化后的代码:
dart复制Widget _buildRoomFilter() {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
_buildRoomChip(null, '全部'),
...RoomType.values.map((room) => _buildRoomChip(room, room.label)),
],
),
);
}
Widget _buildRoomChip(RoomType? room, String label) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: FilterChip(
label: Text(label),
selected: _selectedRoom == room,
onSelected: (selected) {
setState(() {
_selectedRoom = selected ? room : null;
});
},
),
);
}
我们重构了物品添加流程,使其更加高效:
dart复制Future<void> scanBarcode() async {
final barcode = await BarcodeScanner.scan();
if (barcode.isNotEmpty) {
final productInfo = await lookupProduct(barcode);
_itemNameController.text = productInfo.name;
_itemCategory = productInfo.category;
}
}
dart复制Future<void> startVoiceInput() async {
final speech = SpeechToText();
if (await speech.initialize()) {
speech.listen(
onResult: (result) {
_itemNameController.text = result.recognizedWords;
}
);
}
}
使用fl_chart插件实现可视化统计:
dart复制Widget _buildRoomDistributionChart() {
final roomCounts = _calculateRoomDistribution();
return BarChart(
BarChartData(
barGroups: roomCounts.entries.map((entry) {
return BarChartGroupData(
x: entry.key.index,
barRods: [
BarChartRodData(
toY: entry.value.toDouble(),
color: entry.key.color,
)
],
);
}).toList(),
// 其他图表配置...
),
);
}
在鸿蒙设备上,我们特别添加了这些特性:
dart复制void registerQuickService() {
HarmonyAppService.registerQuickAction(
'快速添加物品',
icon: 'resources/base/media/ic_quick_add.png',
action: () => _navigateToAddItem(),
);
}
dart复制Future<void> syncAcrossDevices() async {
final distributedData = await DistributedDataManager.sync(
data: _exportData(),
devices: [DeviceType.PHONE, DeviceType.TABLET],
);
// 处理同步结果...
}
针对鸿蒙设备的特别优化:
dart复制ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ItemCard(
item: items[index],
// 关键:给每个卡片设置唯一的key
key: ValueKey(items[index].id),
);
},
)
dart复制HarmonyImage.asset(
'assets/item_images/${item.id}.jpg',
width: 60,
height: 60,
cacheWidth: 120, // 适当控制缓存分辨率
fadeInDuration: const Duration(milliseconds: 200),
)
我们对比了多种本地存储方案:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| shared_preferences | 简单易用 | 只支持基础数据类型 | 小量简单数据 |
| hive | 高性能 | 需要生成适配器 | 结构化数据 |
| sqflite | 功能强大 | 需要写SQL | 复杂查询需求 |
| 华为DataAbility | 原生集成 | 仅限鸿蒙 | 鸿蒙深度集成 |
最终选择hive作为主要存储,因为:
dart复制// 统一样式方案
ThemeData buildAppTheme() {
return ThemeData(
platform: TargetPlatform.harmony, // 特别指定鸿蒙风格
// 其他主题配置...
);
}
我们正在开发基于机器学习的物品位置推荐:
dart复制class ItemRecommender {
final List<StorageItem> _history;
String recommendLocation(ItemCategory category) {
// 实现基于频率和最近使用的推荐算法
final candidates = _history
.where((item) => item.category == category)
.groupBy((item) => item.locationId)
.entries
.sortedByDescending((e) => e.value.length);
return candidates.firstOrNull()?.key ?? '默认位置';
}
}
通过华为HiLink协议控制智能储物设备:
dart复制Future<void> openSmartDrawer(String locationId) async {
final device = await HiLinkManager.findDevice(locationId);
if (device != null) {
await device.executeCommand(HiLinkCommand.OPEN_DRAWER);
}
}
基于华为CloudDB的实时同步实现:
dart复制void setupCloudSync() {
final cloudDB = CloudDBZoneWrapper(
zoneName: 'StorageAppZone',
objectTypes: [StorageItem.class, StorageLocation.class],
);
cloudDB.subscribeSnapshot((snapshot) {
// 处理数据变更
_updateLocalData(snapshot.changedItems);
});
}
华为官方推荐的打包流程:
bash复制flutter build hap --release --obfuscate --split-debug-info=./debug-info
集成华为AGC性能监控:
dart复制void monitorPerformance() {
AGCPerformance.instance.enableMonitoring(
enableNetwork: true,
enablePageTrack: true,
);
AGCPerformance.setCustomTrace('item_add_flow');
// ...流程代码
AGCPerformance.endTrace('item_add_flow');
}
在实际开发过程中,有几个关键点值得特别注意:
状态管理选择:对于这种数据关系复杂的应用,Riverpod比Provider更合适,因为它能更好地处理异步数据和嵌套对象关系。
本地化考虑:鸿蒙设备用户可能偏好不同的日期格式和排序方式,我们添加了这些本地化处理:
dart复制String formatDate(DateTime date) {
if (isHarmonyOS) {
return DateFormat('yyyy年MM月dd日').format(date);
} else {
return DateFormat.yMd().format(date);
}
}
这个项目最让我惊喜的是Flutter在鸿蒙平台的表现几乎与原生开发无异,而且代码复用率达到了惊人的95%。对于那些既想覆盖传统移动平台又想拥抱鸿蒙生态的团队,Flutter确实是一个非常值得考虑的选择。