开源鸿蒙跨平台:Flutter 新增页面显示收藏和关注
override// 下拉刷新控制器// 网络请求实例// 核心状态变量 - 页面所有数据的载体// 关注用户列表// 页面整体加载状态// 仓库列表单独加载状态// 用户列表单独加载状态String?// 全局错误信息。
一、页面功能总览 & 核心定位
1.1 页面名称与核心功能
本页面文件:repository_page.dart,页面标题「我的收藏」。由上一篇拓展而来,承载两大核心功能:✅ 收藏仓库管理:展示本地收藏的所有 AtomGit/GitCode 仓库列表、支持下拉刷新、左滑取消收藏、二次确认删除✅ 关注用户管理:展示本地关注的所有用户列表、支持下拉刷新、左滑取消关注、二次确认删除
1.2 核心技术栈(本页面用到的所有技术)
- Flutter 基础:
StatefulWidget+TabBar/TabBarView实现双 Tab 页面切换、ListView.builder实现长列表渲染 - 第三方插件:
pull_to_refresh实现下拉刷新功能 - 核心本地存储:鸿蒙适配版 shared_preferences(通过
PersistenceStorage工具类封装调用) - 网络请求:通过
GitCodeApiClient调用 AtomGit/GitCode 的开放 API,获取仓库 / 用户的完整详情数据 - 交互增强:侧滑删除
Dismissible、弹窗确认AlertDialog、加载状态CircularProgressIndicator

数据获取过程
用户打开RepositoryPage
↓
加载动画显示
↓
并行执行:
├─ 从SharedPreferences获取收藏仓库名列表
├─ 从SharedPreferences获取关注用户名列表
↓
对每个仓库名:
├─ 通过搜索API获取仓库详情
├─ 添加到显示列表
↓
对每个用户名:
├─ 通过用户详情API获取用户信息
├─ 添加到显示列表
↓
更新UI显示结果
↓
用户可以:
├─ 下拉刷新重新加载
├─ 左滑删除取消收藏/关注
├─ 点击项目查看详情
二、核心流程
✅ 流程一:页面初始化 & 首次加载所有数据

✅ 流程二:收藏仓库加载 & 数据渲染

三、代码解析
3.1 页面基础结构 & 全局变量定义
class RepositoryPage extends StatefulWidget {
const RepositoryPage({super.key});
@override
State<RepositoryPage> createState() => _RepositoryPageState();
}
class _RepositoryPageState extends State<RepositoryPage> with SingleTickerProviderStateMixin {
// 下拉刷新控制器
final RefreshController _refreshController = RefreshController();
// 网络请求实例
final GitCodeApiClient _apiClient = GitCodeApiClient();
// Tab切换控制器(2个Tab:收藏仓库/关注用户)
late TabController _tabController;
// 核心状态变量 - 页面所有数据的载体
List<GitCodeRepository> _starredRepos = []; // 收藏仓库列表
List<GitCodeUser> _followedUsers = []; // 关注用户列表
bool _isLoading = true; // 页面整体加载状态
bool _loadingRepos = false; // 仓库列表单独加载状态
bool _loadingUsers = false; // 用户列表单独加载状态
String? _errorMessage; // 全局错误信息
}
3.2 核心数据加载方法(所有数据加载的入口)
✔ 加载全部数据 _loadAllData() 【核心主方法】
Future<void> _loadAllData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
// 并发加载:同时加载收藏仓库和关注用户,提升加载效率
await Future.wait([
_loadStarredRepositories(refresh: true),
_loadFollowedUsers(refresh: true),
]);
} catch (e) {
setState(() {
_errorMessage = '加载失败: ${e.toString()}';
});
} finally {
setState(() {
_isLoading = false; // 无论成功失败,最终都关闭加载状态
});
}
}
3.3 收藏仓库相关核心方法
✔ 加载收藏仓库列表 _loadStarredRepositories({bool refresh = false})
Future<void> _loadStarredRepositories({bool refresh = false}) async {
if (_loadingRepos && !refresh) return; // 防重复加载:正在加载且不是刷新,直接返回
setState(() {
_loadingRepos = true;
if (refresh) {
_starredRepos.clear(); // 刷新时清空旧数据,保证数据最新
}
});
try {
// 第一步:从本地存储中获取【收藏的仓库全名列表】 - 核心!!!
final repoFullNames = await PersistenceStorage.getStarredRepositories();
if (repoFullNames.isEmpty) { // 无收藏仓库,直接关闭加载状态
setState(() => _loadingRepos = false);
return;
}
// 第二步:分批并发请求,避免一次性请求过多导致接口报错
final List<GitCodeRepository> loadedRepos = [];
const concurrentLimit = 3; // 每次并发请求3个仓库,可控并发量
for (var i = 0; i < repoFullNames.length; i += concurrentLimit) {
final batch = repoFullNames.sublist(i, i + concurrentLimit > repoFullNames.length ? repoFullNames.length : i + concurrentLimit);
// 并发请求当前批次的仓库详情
final batchResults = await Future.wait(batch.map((fullName) => _fetchRepositoryByFullName(fullName)));
// 过滤空数据+去重,添加到临时列表
for (final result in batchResults) {
if (result != null && !loadedRepos.any((repo) => repo.fullName == result.fullName)) {
loadedRepos.add(result);
}
}
}
// 第三步:更新页面数据,刷新UI
setState(() {
if (refresh) {
_starredRepos = loadedRepos; // 刷新:直接替换列表
} else {
// 加载更多:追加数据并去重
for (final repo in loadedRepos) {
if (!_starredRepos.any((existing) => existing.fullName == repo.fullName)) {
_starredRepos.add(repo);
}
}
}
_loadingRepos = false;
});
} catch (e) {
print('加载收藏仓库失败: $e');
setState(() {
_errorMessage = '加载收藏仓库失败: ${e.toString()}';
_loadingRepos = false;
});
}
}
✔ 取消收藏仓库 _unstarRepository(GitCodeRepository repository)
Future<void> _unstarRepository(GitCodeRepository repository) async {
try {
// 第一步:调用本地存储工具类,删除该仓库的收藏记录
await PersistenceStorage.unstarRepository(repository.fullName);
// 第二步:页面中移除该仓库,刷新UI
setState(() {
_starredRepos.removeWhere((repo) => repo.fullName == repository.fullName);
});
// 第三步:吐司提示操作成功
_showSnackBar('已取消收藏 ${repository.fullName}');
} catch (e) {
_showSnackBar('取消收藏失败: ${e.toString()}', isError: true);
}
}
用户关注与收藏仓库用法相似,这里不再过多赘述
3.4 shared_preferences 核心方法
// 收藏仓库相关
await PersistenceStorage.getStarredRepositories(); // 获取收藏的仓库全名列表
await PersistenceStorage.unstarRepository(fullName); // 取消收藏:删除仓库全名
// 关注用户相关
await PersistenceStorage.getFollowedUsers(); // 获取关注的用户名列表
await PersistenceStorage.unfollowUser(username); // 取消关注:删除用户名
补充:收藏仓库和关注用户的「添加」操作,是在仓库详情页 / 用户详情页调用的,对应方法是:PersistenceStorage.starRepository(fullName) 和 PersistenceStorage.followUser(username),添加后的数据会实时同步到本页面。



欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)