1. 项目背景与需求分析
在开发家具购买记录App时,编辑功能是核心交互场景之一。用户需要能够随时更新家具的详细信息,包括价格变动、使用状态变更或添加新的购买记录。这个功能看似简单,但在OpenHarmony平台上使用Flutter实现时,需要考虑跨平台兼容性、数据持久化和UI交互流畅性等多个维度。
从实际使用场景来看,编辑家具功能需要满足以下几个核心需求:
- 支持快速修改家具的基本属性(名称、价格、购买日期等)
- 能够更新家具的多张展示图片
- 记录家具的维护历史和状态变更
- 在不同设备间保持数据同步
2. 技术架构设计
2.1 跨平台兼容性方案
由于项目基于Flutter for OpenHarmony,我们需要特别注意OpenHarmony平台的特有API调用。在编辑页面中,图片选择功能需要针对不同平台进行适配:
dart复制Future<void> _pickImage() async {
if (Platform.isOpenHarmony) {
// OpenHarmony专用图片选择器
final result = await OpenHarmonyImagePicker.pickImage();
if (result != null) {
setState(() => _images.add(result));
}
} else {
// 其他平台使用image_picker插件
final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
setState(() => _images.add(File(pickedFile.path)));
}
}
}
2.2 状态管理方案
编辑页面涉及多个表单字段和图片上传状态,我们采用Riverpod进行状态管理:
dart复制final furnitureEditProvider = StateNotifierProvider<FurnitureEditNotifier, FurnitureEditState>((ref) {
return FurnitureEditNotifier();
});
class FurnitureEditState {
final FurnitureItem originalItem;
final String name;
final double price;
// 其他字段...
final List<File> newImages;
final bool isSaving;
// 构造函数和copyWith方法...
}
class FurnitureEditNotifier extends StateNotifier<FurnitureEditState> {
FurnitureEditNotifier() : super(FurnitureEditState.initial());
void updateName(String newName) {
state = state.copyWith(name: newName);
}
// 其他更新方法...
}
3. 核心功能实现
3.1 表单验证系统
家具编辑需要严格的表单验证,我们创建一个集中式的验证器:
dart复制class FurnitureValidator {
static String? name(String? value) {
if (value == null || value.isEmpty) {
return '名称不能为空';
}
if (value.length > 50) {
return '名称过长(最多50字符)';
}
return null;
}
static String? price(String? value) {
if (value == null || value.isEmpty) {
return '价格不能为空';
}
final parsed = double.tryParse(value);
if (parsed == null) {
return '请输入有效数字';
}
if (parsed <= 0) {
return '价格必须大于0';
}
return null;
}
// 其他验证规则...
}
3.2 图片处理流程
家具图片编辑是核心功能,需要处理多图上传、预览和删除:
dart复制Widget _buildImageGrid() {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: _images.length + 1,
itemBuilder: (context, index) {
if (index == _images.length) {
return _buildAddButton();
}
return Stack(
children: [
_buildImageItem(_images[index]),
Positioned(
top: 4,
right: 4,
child: _buildDeleteButton(index),
),
],
);
},
);
}
4. 数据持久化方案
4.1 本地数据库设计
使用Hive进行本地存储,定义家具数据模型:
dart复制@HiveType(typeId: 1)
class FurnitureItem extends HiveObject {
@HiveField(0)
String id;
@HiveField(1)
String name;
@HiveField(2)
double price;
@HiveField(3)
List<String> imageUrls;
// 其他字段和方法...
}
4.2 云端同步机制
实现本地修改后的自动同步策略:
dart复制Future<void> _saveChanges() async {
try {
state = state.copyWith(isSaving: true);
// 本地保存
await _localDB.save(state.toFurnitureItem());
// 如果有网络连接则同步到云端
if (await _networkChecker.hasConnection()) {
await _cloudService.syncItem(state.toFurnitureItem());
} else {
// 加入待同步队列
await _syncQueue.addPendingSync(state.toFurnitureItem());
}
// 保存成功导航回上一页
Navigator.pop(context, true);
} catch (e) {
// 错误处理...
} finally {
state = state.copyWith(isSaving: false);
}
}
5. 交互优化与细节处理
5.1 键盘交互优化
针对价格输入等数字键盘场景的特殊处理:
dart复制TextField(
controller: _priceController,
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}')),
TextInputFormatter.withFunction((oldValue, newValue) {
// 自动补全小数点后两位
if (newValue.text.contains('.')) {
final parts = newValue.text.split('.');
if (parts[1].length > 2) {
return oldValue;
}
}
return newValue;
}),
],
decoration: InputDecoration(
prefixText: '¥ ',
hintText: '0.00',
),
);
5.2 保存状态提示
长时间操作时的用户反馈设计:
dart复制FutureBuilder<void>(
future: _saveFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Theme.of(context).primaryColor),
);
}
return ElevatedButton(
onPressed: _validateAndSave,
child: const Text('保存修改'),
);
},
)
6. 测试与调试要点
6.1 边界条件测试
特别注意以下测试场景:
- 家具名称包含特殊字符
- 价格输入超大数值(超过数据库字段限制)
- 同时上传多张大尺寸图片
- 在弱网环境下尝试保存
- 编辑过程中突然关闭应用
6.2 性能优化检查
使用Flutter性能工具重点监控:
- 图片加载时的内存占用
- 表单频繁更新时的UI重绘
- 数据库操作的执行时间
- 页面跳转时的动画流畅度
7. 实际开发中的经验总结
在实现编辑功能时,有几个关键点值得特别注意:
-
图片处理策略:对于家具图片,我们最终采用了先压缩后上传的方案。原图在上传前会压缩到合理尺寸(最长边不超过2000px),既保证了显示质量,又减少了存储和传输开销。实测下来,这种方法在低端设备上也能保持流畅的用户体验。
-
表单状态管理:最初尝试使用多个独立的TextEditingController,后来发现当表单字段较多时(家具编辑有15+字段),这种方案难以维护。改用单一状态对象管理所有字段后,代码可读性和可维护性大幅提升。
-
跨平台差异处理:OpenHarmony的文件系统访问权限与其他平台有所不同。我们封装了一个平台适配层,统一处理文件路径和访问权限,避免了业务代码中充斥平台判断逻辑。
-
撤销操作支持:在用户反馈中,意外修改是常见问题。我们后来增加了编辑历史栈,支持最多5步撤销,显著提升了用户体验。这个功能在实现时需要注意内存管理,避免保存过大或过多的历史状态。
-
自动保存策略:对于长时间编辑场景,实现了每30秒自动保存草稿的功能。但要注意处理好自动保存和手动保存的冲突,我们采用乐观锁机制来避免数据竞争。
