fix(client): 修正 ChangeNotifier 监听生命周期

This commit is contained in:
Zhou Weidong committed 2026-10-22 19:14:35 +08:00
1 parent 4291031ace
commit 8936c3d6eb
7 files changed
+286 -269

No files matched your search

+92 -98
View File
@@ -105,22 +105,25 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
walletBadge: walletBadge,
),
Expanded(
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: ListenableBuilder(
listenable: widget.feedController,
builder: (context, _) => PageView.builder(
key: const Key('home-primary-page-view'),
controller: _pageController,
itemCount: HomePrimaryTab.values.length,
onPageChanged: (index) => setState(
() => _selectedPrimary = HomePrimaryTab.values[index],
),
child: _tabGrid(
context,
l10n,
tab: HomePrimaryTab.values[index],
shortcuts: shortcuts,
itemBuilder: (context, index) => _KeepAlivePage(
key: PageStorageKey(
'home-primary-page-${HomePrimaryTab.values[index].name}',
),
child: _tabGrid(
context,
l10n,
tab: HomePrimaryTab.values[index],
shortcuts: shortcuts,
),
),
),
),
@@ -152,90 +155,81 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
required HomePrimaryTab tab,
required List<HomeGridCategoryShortcut> shortcuts,
}) {
return ListenableBuilder(
listenable: widget.feedController,
builder: (context, _) {
if (widget.feedController.loadingFirstPage) {
return const Center(
child: SizedBox.square(
dimension: 24,
child: CircularProgressIndicator(strokeWidth: 2),
if (widget.feedController.loadingFirstPage) {
return const Center(
child: SizedBox.square(
dimension: 24,
child: CircularProgressIndicator(strokeWidth: 2),
),
);
}
final tag = _selectedTags[tab];
final dramas = _dramasFor(tab, tag, shortcuts);
return LayoutBuilder(
builder: (context, constraints) {
final itemWidth =
(constraints.maxWidth -
AppDimens.feedPageHorizontal * 2 -
AppDimens.homeGridGap * 2) /
3;
final itemExtent =
itemWidth / AppDimens.cardCoverAspectRatio +
AppDimens.homeCardBodyExtent;
return NotificationListener<ScrollNotification>(
onNotification: _onScroll,
child: AppPullToRefresh(
key: const Key('home-grid-refresh'),
onRefresh: _refresh,
child: CustomScrollView(
key: const Key('home-grid-scroll'),
controller: _scrollControllers[tab],
physics: AppPullToRefresh.physics,
slivers: [
if (dramas.isEmpty)
SliverFillRemaining(
hasScrollBody: false,
child: _emptyState(l10n, tab, tag),
)
else
SliverPadding(
padding: const EdgeInsets.symmetric(
horizontal: AppDimens.feedPageHorizontal,
),
sliver: SliverGrid(
key: const Key('home-grid-cards'),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: AppDimens.homeGridGap,
mainAxisSpacing: AppDimens.homeGridRowGap,
mainAxisExtent: itemExtent,
),
delegate: SliverChildBuilderDelegate(
(context, index) => HomeFeedCard(
drama: dramas[index],
onTap: () => widget.onOpenDrama(dramas[index]),
),
childCount: dramas.length,
),
),
),
if (dramas.isNotEmpty)
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(bottom: AppDimens.spaceXl),
child: PagedListFooter(
loading: widget.feedController.loadingMore,
hasMore: widget.feedController.hasMore,
hasItems: dramas.isNotEmpty,
errorMessage: widget.feedController.lastError == null
? null
: l10n.catalogError,
onRetry: widget.feedController.loadMore,
),
),
),
],
),
);
}
final tag = _selectedTags[tab];
final dramas = _dramasFor(tab, tag, shortcuts);
return LayoutBuilder(
builder: (context, constraints) {
final itemWidth =
(constraints.maxWidth -
AppDimens.feedPageHorizontal * 2 -
AppDimens.homeGridGap * 2) /
3;
final itemExtent =
itemWidth / AppDimens.cardCoverAspectRatio +
AppDimens.homeCardBodyExtent;
return NotificationListener<ScrollNotification>(
onNotification: _onScroll,
child: AppPullToRefresh(
key: const Key('home-grid-refresh'),
onRefresh: _refresh,
child: CustomScrollView(
key: const Key('home-grid-scroll'),
controller: _scrollControllers[tab],
physics: AppPullToRefresh.physics,
slivers: [
if (dramas.isEmpty)
SliverFillRemaining(
hasScrollBody: false,
child: _emptyState(l10n, tab, tag),
)
else
SliverPadding(
padding: const EdgeInsets.symmetric(
horizontal: AppDimens.feedPageHorizontal,
),
sliver: SliverGrid(
key: const Key('home-grid-cards'),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: AppDimens.homeGridGap,
mainAxisSpacing: AppDimens.homeGridRowGap,
mainAxisExtent: itemExtent,
),
delegate: SliverChildBuilderDelegate(
(context, index) => HomeFeedCard(
drama: dramas[index],
onTap: () => widget.onOpenDrama(dramas[index]),
),
childCount: dramas.length,
),
),
),
if (dramas.isNotEmpty)
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(
bottom: AppDimens.spaceXl,
),
child: PagedListFooter(
loading: widget.feedController.loadingMore,
hasMore: widget.feedController.hasMore,
hasItems: dramas.isNotEmpty,
errorMessage:
widget.feedController.lastError == null
? null
: l10n.catalogError,
onRetry: widget.feedController.loadMore,
),
),
),
],
),
),
);
},
),
);
},
);