perf(discover): 剧场与新片页网格改为按行懒加载
flutter-ci / test (push) Failing after 19m39s

双列网格原来是两个 Column 一次性建出所有卡片,翻几页后上百张卡连同封面都留在树上;
现在改成按行的 SliverList,只构建可见行,剧场页/新片页/搜索结果的滚动容器一并换成 sliver。
搜索结果、加载失败等状态同步改成 sliver,滚动位置与下拉刷新行为保持不变。
This commit is contained in:
Vicky authored and trae-solo-agent committed 2026-10-29 11:38:21 +08:00
1 parent 4aaa5bbd60
commit fe49527dd8
6 files changed
+193 -145

No files matched your search

+69 -47
View File
@@ -135,64 +135,81 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
child: AppPullToRefresh(
key: const Key('new-releases-refresh'),
onRefresh: _refresh,
child: ListView(
child: CustomScrollView(
key: const Key('new-releases-list'),
controller: _scroll,
physics: AppPullToRefresh.physics,
padding: const EdgeInsets.only(bottom: 24),
children: hero == null
slivers: hero == null
? [
SizedBox(
height: 420,
child: Center(
child: Text(
l10n.noStories,
key: const Key('new-releases-empty'),
style: const TextStyle(
color: AppColors.muted,
SliverToBoxAdapter(
child: SizedBox(
height: 420,
child: Center(
child: Text(
l10n.noStories,
key: const Key('new-releases-empty'),
style: const TextStyle(
color: AppColors.muted,
),
),
),
),
),
]
: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
child: _heroCard(context, l10n, hero),
),
child: _heroCard(context, l10n, hero),
),
const SizedBox(height: 14),
const _FilmStrip(),
const SizedBox(height: 14),
const SliverToBoxAdapter(
child: SizedBox(height: 14),
),
const SliverToBoxAdapter(child: _FilmStrip()),
const SliverToBoxAdapter(
child: SizedBox(height: 14),
),
if (more.isNotEmpty) ...[
_moreHeader(l10n),
const SizedBox(height: 10),
SizedBox(
height: _rowHeight,
child: ListView.separated(
key: const Key('new-releases-row'),
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(
horizontal: 16,
SliverToBoxAdapter(
child: _moreHeader(l10n),
),
const SliverToBoxAdapter(
child: SizedBox(height: 10),
),
SliverToBoxAdapter(
child: SizedBox(
height: _rowHeight,
child: ListView.separated(
key: const Key('new-releases-row'),
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
itemCount: more.length,
separatorBuilder: (_, _) =>
const SizedBox(width: 10),
itemBuilder: (context, index) =>
_moreCard(
context,
l10n,
more[index],
index,
),
),
itemCount: more.length,
separatorBuilder: (_, _) =>
const SizedBox(width: 10),
itemBuilder: (context, index) =>
_moreCard(
context,
l10n,
more[index],
index,
),
),
),
],
const SizedBox(height: 20),
_allHeader(l10n),
const SizedBox(height: 10),
DramaGrid(
const SliverToBoxAdapter(
child: SizedBox(height: 20),
),
SliverToBoxAdapter(child: _allHeader(l10n)),
const SliverToBoxAdapter(
child: SizedBox(height: 10),
),
SliverDramaGrid(
key: const Key('new-releases-all-grid'),
l10n: l10n,
dramas: visible,
@@ -200,12 +217,17 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
playDramaFromCatalog(context, drama),
),
),
PagedLoadFooter(
loading: pager.loading,
hasMore: pager.hasMore,
hasItems: visible.isNotEmpty,
loadMoreKey: const Key(
'new-releases-load-more',
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(bottom: 24),
child: PagedLoadFooter(
loading: pager.loading,
hasMore: pager.hasMore,
hasItems: visible.isNotEmpty,
loadMoreKey: const Key(
'new-releases-load-more',
),
),
),
),
],