flutter_for_openharmony口腔护理app实战+我的收藏实现
本文介绍了如何在Flutter应用中实现收藏管理功能。主要内容包括: 页面结构设计 使用StatelessWidget构建收藏页面 通过Consumer监听数据变化 过滤出已收藏的文章列表 核心功能实现 空状态处理:显示爱心图标和引导文字 收藏列表:使用ListView.builder构建 文章卡片:包含标题、分类标签和取消收藏按钮 交互功能:点击跳转详情页和取消收藏 数据管理 通过AppProv

前言
收藏功能是内容类应用的标配功能。用户在浏览文章时,可以将感兴趣的内容收藏起来,方便日后查阅。在口腔护理应用中,用户可以收藏有价值的口腔健康知识文章,建立自己的知识库。
本文将介绍如何在 Flutter 中实现一个功能完善的收藏管理页面。
功能设计
收藏页面需要实现以下功能:
- 收藏列表:展示所有已收藏的文章
- 空状态处理:没有收藏时显示友好提示
- 取消收藏:支持在列表中直接取消收藏
- 跳转详情:点击文章跳转到详情页
页面基础结构
收藏页面使用 StatelessWidget 实现:
class FavoritePage extends StatelessWidget {
const FavoritePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('我的收藏')),
body: Consumer<AppProvider>(
builder: (context, provider, _) {
final favorites = provider.articles
.where((a) => a.isFavorite).toList();
使用 Consumer 监听数据变化,通过 where 方法过滤出已收藏的文章。
空状态处理
没有收藏时显示友好的空状态:
if (favorites.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.favorite_border, size: 80,
color: Colors.grey.shade300),
const SizedBox(height: 16),
Text('暂无收藏',
style: TextStyle(color: Colors.grey.shade500, fontSize: 16)),
const SizedBox(height: 8),
Text('去知识库收藏感兴趣的文章吧',
style: TextStyle(color: Colors.grey.shade400)),
],
),
);
}
空状态使用爱心图标和引导文字,提示用户去收藏文章。
收藏列表构建
使用 ListView.builder 构建收藏列表:
return ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: favorites.length,
itemBuilder: (context, index) {
final article = favorites[index];
return GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ArticleDetailPage(article: article)),
),
点击文章卡片跳转到详情页,使用 MaterialPageRoute 进行页面导航。
文章卡片设计
收藏的文章使用卡片形式展示:
child: Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: const Color(0xFF26A69A).withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: const Icon(Icons.article,
color: Color(0xFF26A69A)),
),
左侧使用方形图标容器,主题色浅色背景配合文章图标。
文章标题和分类标签:
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
article.title,
style: const TextStyle(fontWeight: FontWeight.bold),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: const Color(0xFF26A69A).withOpacity(0.1),
borderRadius: BorderRadius.circular(4),
),
child: Text(
article.category,
style: const TextStyle(
color: Color(0xFF26A69A), fontSize: 11),
),
),
],
),
),
标题最多显示两行,超出部分显示省略号。分类标签使用小型彩色标签形式。
取消收藏按钮:
IconButton(
icon: const Icon(Icons.favorite, color: Colors.red),
onPressed: () => provider.toggleArticleFavorite(article.id),
),
],
),
),
);
},
);
},
),
);
}
}
红色实心爱心图标表示已收藏状态,点击可取消收藏。
Provider 收藏管理
在 AppProvider 中管理收藏状态:
void toggleArticleFavorite(String id) {
final index = _articles.indexWhere((a) => a.id == id);
if (index != -1) {
final old = _articles[index];
_articles[index] = OralArticle(
id: old.id,
title: old.title,
content: old.content,
category: old.category,
publishDate: old.publishDate,
readCount: old.readCount,
isFavorite: !old.isFavorite,
);
notifyListeners();
}
}
切换收藏状态后通知界面更新。
收藏数量统计
获取收藏数量:
int get favoriteCount => _articles.where((a) => a.isFavorite).length;
可以在个人中心显示收藏数量。
批量取消收藏
添加批量取消收藏功能:
void clearAllFavorites() {
for (int i = 0; i < _articles.length; i++) {
if (_articles[i].isFavorite) {
final old = _articles[i];
_articles[i] = OralArticle(
id: old.id,
title: old.title,
content: old.content,
category: old.category,
publishDate: old.publishDate,
readCount: old.readCount,
isFavorite: false,
);
}
}
notifyListeners();
}
清空所有收藏。
清空收藏确认
在页面添加清空收藏的入口:
AppBar(
title: const Text('我的收藏'),
actions: [
if (favorites.isNotEmpty)
IconButton(
icon: const Icon(Icons.delete_outline),
onPressed: () {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('清空收藏'),
content: const Text('确定要清空所有收藏吗?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx),
child: const Text('取消')),
ElevatedButton(
onPressed: () {
provider.clearAllFavorites();
Navigator.pop(ctx);
},
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
child: const Text('清空'),
),
],
),
);
},
),
],
)
清空前显示确认对话框,避免误操作。
收藏分类筛选
按文章分类筛选收藏:
String _selectedCategory = '全部';
List<OralArticle> get filteredFavorites {
var result = _articles.where((a) => a.isFavorite).toList();
if (_selectedCategory != '全部') {
result = result.where((a) => a.category == _selectedCategory).toList();
}
return result;
}
支持按分类查看收藏的文章。
筛选按钮组
添加分类筛选按钮:
SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
children: categories.map((category) => Padding(
padding: const EdgeInsets.only(right: 8),
child: FilterChip(
label: Text(category),
selected: _selectedCategory == category,
onSelected: (selected) {
setState(() => _selectedCategory = category);
},
selectedColor: const Color(0xFF26A69A).withOpacity(0.2),
),
)).toList(),
),
)
使用 FilterChip 实现分类筛选。
收藏排序功能
支持按收藏时间排序:
List<OralArticle> get sortedFavorites {
final result = _articles.where((a) => a.isFavorite).toList();
result.sort((a, b) => b.favoriteDate!.compareTo(a.favoriteDate!));
return result;
}
最新收藏的文章排在前面。
收藏时间记录
在数据模型中添加收藏时间:
class OralArticle {
// ...
final DateTime? favoriteDate;
OralArticle({
// ...
this.favoriteDate,
});
}
收藏时记录时间,用于排序和显示。
显示收藏时间
在卡片中显示收藏时间:
if (article.favoriteDate != null)
Text(
'收藏于 ${DateFormat('MM-dd').format(article.favoriteDate!)}',
style: TextStyle(color: Colors.grey.shade400, fontSize: 11),
),
显示收藏的日期。
滑动删除功能
添加滑动删除收藏:
Dismissible(
key: Key(article.id),
direction: DismissDirection.endToStart,
background: Container(
color: Colors.red,
alignment: Alignment.centerRight,
padding: const EdgeInsets.only(right: 16),
child: const Icon(Icons.delete, color: Colors.white),
),
onDismissed: (direction) {
provider.toggleArticleFavorite(article.id);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('已取消收藏'),
action: SnackBarAction(
label: '撤销',
onPressed: () {
provider.toggleArticleFavorite(article.id);
},
),
),
);
},
child: _buildArticleCard(article),
)
滑动删除后显示撤销选项。
搜索收藏功能
添加收藏搜索:
TextField(
decoration: InputDecoration(
hintText: '搜索收藏',
prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
filled: true,
fillColor: Colors.white,
),
onChanged: (value) {
setState(() => _searchKeyword = value);
},
)
List<OralArticle> get searchedFavorites {
if (_searchKeyword.isEmpty) return favorites;
return favorites.where((a) =>
a.title.contains(_searchKeyword)
).toList();
}
支持按标题搜索收藏的文章。
收藏导出功能
导出收藏列表:
String exportFavorites() {
final buffer = StringBuffer();
buffer.writeln('我的收藏');
buffer.writeln('导出时间:${DateFormat('yyyy-MM-dd').format(DateTime.now())}');
buffer.writeln('');
for (var article in favorites) {
buffer.writeln('标题:${article.title}');
buffer.writeln('分类:${article.category}');
buffer.writeln('---');
}
return buffer.toString();
}
可以将收藏列表导出为文本。
收藏同步功能
如果有账号系统,可以同步收藏:
Future<void> syncFavorites() async {
// 上传本地收藏到服务器
final localFavorites = _articles.where((a) => a.isFavorite).toList();
await api.uploadFavorites(localFavorites);
// 下载服务器收藏到本地
final remoteFavorites = await api.downloadFavorites();
// 合并收藏
}
实现多设备收藏同步。
空状态优化
为空状态添加快捷入口:
if (favorites.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.favorite_border, size: 80, color: Colors.grey.shade300),
const SizedBox(height: 16),
Text('暂无收藏',
style: TextStyle(color: Colors.grey.shade500, fontSize: 16)),
const SizedBox(height: 8),
Text('去知识库收藏感兴趣的文章吧',
style: TextStyle(color: Colors.grey.shade400)),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: () {
// 跳转到知识库
},
icon: const Icon(Icons.explore),
label: const Text('去发现'),
),
],
),
);
}
添加跳转到知识库的快捷按钮。
总结
本文详细介绍了口腔护理 App 中收藏功能的实现。通过合理的界面设计和交互逻辑,我们构建了一个实用的收藏管理页面。核心技术点包括:
- 使用
where方法过滤收藏的文章 - 通过
GestureDetector实现点击跳转 - 使用
IconButton实现取消收藏 - 友好的空状态处理
收藏功能帮助用户管理感兴趣的内容,是提升用户体验的重要功能。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)