feat(home): 支持滑动切换首页分类

This commit is contained in:
Zhou Weidong committed 2026-10-22 19:05:55 +08:00
1 parent b921f79a71
commit 5282194ca5
3 files changed
+86 -8

No files matched your search

+58 -8
View File
@@ -43,6 +43,7 @@ class HomeFeedGrid extends StatefulWidget {
class _HomeFeedGridState extends State<HomeFeedGrid> {
HomePrimaryTab _selectedPrimary = HomePrimaryTab.featured;
late final PageController _pageController;
late final Map<HomePrimaryTab, ScrollController> _scrollControllers;
final Map<HomePrimaryTab, String?> _selectedTags = {
for (final tab in HomePrimaryTab.values) tab: null,
@@ -51,6 +52,7 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
@override
void initState() {
super.initState();
_pageController = PageController(initialPage: _selectedPrimary.index);
_scrollControllers = {
for (final tab in HomePrimaryTab.values) tab: ScrollController(),
};
@@ -58,6 +60,7 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
@override
void dispose() {
_pageController.dispose();
for (final controller in _scrollControllers.values) {
controller.dispose();
}
@@ -93,19 +96,30 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
tags: tags,
selectedPrimary: _selectedPrimary,
selectedTag: activeTag,
onPrimarySelected: (tab) =>
setState(() => _selectedPrimary = tab),
onPrimarySelected: _selectPrimary,
onTagSelected: (tag) =>
setState(() => _selectedTags[_selectedPrimary] = tag),
walletBadge: walletBadge,
),
Expanded(
child: IndexedStack(
index: _selectedPrimary.index,
children: [
for (final tab in HomePrimaryTab.values)
_tabGrid(context, l10n, tab: tab, shortcuts: shortcuts),
],
child: PageView.builder(
key: const Key('home-primary-page-view'),
controller: _pageController,
itemCount: HomePrimaryTab.values.length,
onPageChanged: (index) => setState(
() => _selectedPrimary = HomePrimaryTab.values[index],
),
itemBuilder: (context, index) => _KeepAlivePage(
key: PageStorageKey(
'home-primary-page-${HomePrimaryTab.values[index].name}',
),
child: _tabGrid(
context,
l10n,
tab: HomePrimaryTab.values[index],
shortcuts: shortcuts,
),
),
),
),
],
@@ -114,6 +128,21 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
);
}
void _selectPrimary(HomePrimaryTab tab) {
if (tab == _selectedPrimary) return;
if (!_pageController.hasClients) {
setState(() => _selectedPrimary = tab);
return;
}
unawaited(
_pageController.animateToPage(
tab.index,
duration: AppDimens.homePrimaryTabAnimationDuration,
curve: Curves.easeOut,
),
);
}
Widget _tabGrid(
BuildContext context,
AppLocalizations l10n, {
@@ -329,3 +358,24 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
);
}
}
class _KeepAlivePage extends StatefulWidget {
const _KeepAlivePage({super.key, required this.child});
final Widget child;
@override
State<_KeepAlivePage> createState() => _KeepAlivePageState();
}
class _KeepAlivePageState extends State<_KeepAlivePage>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return widget.child;
}
}