Flutter for OpenHarmony 家具购买记录App实战:收藏夹实现
摘要:本文介绍了家具收藏功能的实现方案。收藏页面以卡片列表形式展示用户收藏的家具,包含图片占位、名称、品牌、房间和价格信息,右下角提供取消收藏按钮。页面设计简洁直观,空状态显示引导提示。技术实现采用Flutter框架,通过GetX状态管理收藏数据,支持添加/移除收藏操作。家具详情页集成收藏按钮,实时反馈收藏状态。该功能帮助用户快速访问常用家具,提升用户体验。
收藏夹页面展示用户收藏的家具。用户可以把重要的或喜欢的家具加入收藏,方便以后快速查看。这个页面的设计比较简洁,主要是一个卡片列表。
做收藏功能的时候我在想,有些家具可能是用户特别喜欢的,或者是需要重点关注的(比如快过保的),加入收藏后就不用在长长的列表里找了。
页面设计思路
收藏夹页面的设计要点:
- 列表展示收藏的家具
- 每个卡片显示家具图片占位、名称、品牌、房间、价格
- 卡片右下角有取消收藏按钮
- 没有收藏时显示空状态引导
卡片设计比普通列表项更丰富,左边有图片占位区域,让页面更有视觉层次。
页面基础结构
收藏夹页面用 StatelessWidget:
class FavoritesPage extends StatelessWidget {
const FavoritesPage({super.key});
收藏数据暂时写死:
final _favorites = const [
{'name': '北欧实木沙发', 'room': '客厅', 'brand': '宜家', 'price': 12800.0},
{'name': '智能升降书桌', 'room': '书房', 'brand': '乐歌', 'price': 3200.0},
{'name': '真皮双人床', 'room': '卧室', 'brand': '顾家', 'price': 8500.0},
];
每个收藏项有四个属性:名称、房间、品牌、价格。
build 方法实现
build 方法构建整个页面:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFFAF8F5),
appBar: AppBar(
title: const Text('我的收藏'),
backgroundColor: const Color(0xFF8B4513),
foregroundColor: Colors.white
),
body: _favorites.isEmpty
? _buildEmpty()
: ListView.builder(
padding: EdgeInsets.all(16.w),
itemCount: _favorites.length,
itemBuilder: (context, index) => _buildFavoriteCard(_favorites[index]),
),
);
}
根据收藏列表是否为空显示不同内容。
空状态组件
没有收藏时显示空状态:
Widget _buildEmpty() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.favorite_border, size: 80.sp, color: Colors.grey[300]),
SizedBox(height: 16.h),
Text('暂无收藏', style: TextStyle(color: Colors.grey[500], fontSize: 16.sp)),
SizedBox(height: 8.h),
Text('点击家具详情页的❤️添加收藏',
style: TextStyle(color: Colors.grey[400], fontSize: 13.sp)),
],
),
);
}
空状态显示一个空心爱心图标和引导文字,告诉用户如何添加收藏。
收藏卡片组件
每个收藏是一个横向卡片:
Widget _buildFavoriteCard(Map<String, dynamic> item) {
return Container(
margin: EdgeInsets.only(bottom: 12.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r)
),
child: Row(
children: [
Container(
width: 100.w,
height: 100.w,
decoration: BoxDecoration(
color: const Color(0xFF8B4513).withOpacity(0.1),
borderRadius: BorderRadius.horizontal(left: Radius.circular(16.r)),
),
child: Center(
child: Icon(Icons.chair, size: 40.sp,
color: const Color(0xFF8B4513).withOpacity(0.5))
),
),
左边是图片占位区域,用浅棕色背景和半透明图标。实际项目中这里应该显示家具的真实图片。
BorderRadius.horizontal(left: ...) 只给左边设置圆角,和卡片的左边圆角对齐。
家具信息区域
右边是家具信息:
Expanded(
child: Padding(
padding: EdgeInsets.all(12.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(item['name'] as String, style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15.sp
)),
SizedBox(height: 4.h),
Text('${item['brand']} · ${item['room']}', style: TextStyle(
color: Colors.grey[600],
fontSize: 12.sp
)),
SizedBox(height: 8.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('¥${(item['price'] as double).toStringAsFixed(0)}',
style: TextStyle(
color: const Color(0xFF8B4513),
fontWeight: FontWeight.bold,
fontSize: 16.sp
)),
IconButton(
icon: const Icon(Icons.favorite, color: Colors.red),
onPressed: () => Get.snackbar('已取消', '已从收藏中移除'),
),
],
),
],
),
),
),
],
),
);
}
显示名称、品牌和房间、价格。右下角是红色实心爱心按钮,点击取消收藏。
收藏状态管理
实际项目中,收藏状态应该用状态管理:
class FavoritesController extends GetxController {
final favorites = <Map<String, dynamic>>[].obs;
void addFavorite(Map<String, dynamic> item) {
if (!favorites.any((f) => f['id'] == item['id'])) {
favorites.add(item);
}
}
void removeFavorite(String id) {
favorites.removeWhere((f) => f['id'] == id);
}
bool isFavorite(String id) {
return favorites.any((f) => f['id'] == id);
}
}
用 GetX 的响应式变量管理收藏列表,添加、移除、判断是否收藏都通过 Controller 操作。
家具详情页的收藏按钮
在家具详情页添加收藏按钮:
IconButton(
icon: Icon(
controller.isFavorite(furniture['id'])
? Icons.favorite
: Icons.favorite_border,
color: controller.isFavorite(furniture['id'])
? Colors.red
: Colors.grey,
),
onPressed: () {
if (controller.isFavorite(furniture['id'])) {
controller.removeFavorite(furniture['id']);
Get.snackbar('已取消', '已从收藏中移除');
} else {
controller.addFavorite(furniture);
Get.snackbar('已收藏', '已添加到收藏夹');
}
},
)
根据收藏状态显示实心或空心爱心,点击切换状态。
收藏排序
收藏列表可以支持排序:
enum SortType { byTime, byName, byPrice }
List<Map<String, dynamic>> _sortFavorites(SortType type) {
final list = List<Map<String, dynamic>>.from(_favorites);
switch (type) {
case SortType.byTime:
// 按收藏时间排序
break;
case SortType.byName:
list.sort((a, b) => (a['name'] as String).compareTo(b['name'] as String));
break;
case SortType.byPrice:
list.sort((a, b) => (a['price'] as double).compareTo(b['price'] as double));
break;
}
return list;
}
可以在 AppBar 加一个排序按钮,让用户选择排序方式。
批量操作
可以支持批量取消收藏:
bool _isSelecting = false;
Set<String> _selectedIds = {};
Widget _buildSelectableCard(Map<String, dynamic> item) {
final isSelected = _selectedIds.contains(item['id']);
return GestureDetector(
onTap: () {
if (_isSelecting) {
setState(() {
if (isSelected) {
_selectedIds.remove(item['id']);
} else {
_selectedIds.add(item['id']);
}
});
}
},
child: Stack(
children: [
_buildFavoriteCard(item),
if (_isSelecting)
Positioned(
top: 8, right: 8,
child: Icon(
isSelected ? Icons.check_circle : Icons.radio_button_unchecked,
color: isSelected ? const Color(0xFF8B4513) : Colors.grey,
),
),
],
),
);
}
长按进入选择模式,点击选中/取消选中,底部显示批量操作按钮。
小结
收藏夹页面展示用户收藏的家具,用横向卡片布局,左边是图片占位,右边是家具信息。空状态显示引导文字,告诉用户如何添加收藏。
收藏功能需要状态管理,在家具详情页添加收藏按钮,收藏夹页面显示收藏列表。
下一篇会讲商家管理页面的实现,展示购买家具的商家信息。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐




所有评论(0)