双列网格原来是两个 Column 一次性建出所有卡片,翻几页后上百张卡连同封面都留在树上; 现在改成按行的 SliverList,只构建可见行,剧场页/新片页/搜索结果的滚动容器一并换成 sliver。 搜索结果、加载失败等状态同步改成 sliver,滚动位置与下拉刷新行为保持不变。
This commit is contained in:
1 parent
4aaa5bbd60
commit
fe49527dd8
6 files changed
+193
-145
No files matched your search
@@ -153,14 +153,19 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
||||
edgeOffset: _stickyHeaderHeight + 8,
|
||||
onRefresh: () =>
|
||||
Future.wait([categories.load(), theater.refreshCurrent()]),
|
||||
child: ListView(
|
||||
child: CustomScrollView(
|
||||
controller: logic.scroll,
|
||||
physics: AppPullToRefresh.physics,
|
||||
padding: EdgeInsets.only(
|
||||
top: showHeader ? _stickyHeaderHeight : 0,
|
||||
bottom: AppDimens.spaceXl,
|
||||
),
|
||||
children: _content(l10n, categories),
|
||||
slivers: [
|
||||
if (showHeader)
|
||||
const SliverToBoxAdapter(
|
||||
child: SizedBox(height: _stickyHeaderHeight),
|
||||
),
|
||||
..._content(l10n, categories),
|
||||
const SliverToBoxAdapter(
|
||||
child: SizedBox(height: AppDimens.spaceXl),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -228,12 +233,12 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
||||
];
|
||||
}
|
||||
if (categories.loading && categories.categories.isEmpty) {
|
||||
return [_block(const CircularProgressIndicator(strokeWidth: 2))];
|
||||
return [_sliverBlock(const CircularProgressIndicator(strokeWidth: 2))];
|
||||
}
|
||||
final error = categories.error;
|
||||
if (error != null) {
|
||||
return [
|
||||
_block(
|
||||
_sliverBlock(
|
||||
EmptyState(
|
||||
key: const Key('home-categories-error'),
|
||||
icon: Icons.cloud_off_rounded,
|
||||
@@ -253,12 +258,12 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
||||
];
|
||||
}
|
||||
if (theater.loadingFirstPage) {
|
||||
return [_block(const CircularProgressIndicator(strokeWidth: 2))];
|
||||
return [_sliverBlock(const CircularProgressIndicator(strokeWidth: 2))];
|
||||
}
|
||||
final theaterError = theater.lastError;
|
||||
if (theaterError != null && theater.dramas.isEmpty) {
|
||||
return [
|
||||
_block(
|
||||
_sliverBlock(
|
||||
EmptyState(
|
||||
key: const Key('home-categories-error'),
|
||||
icon: Icons.cloud_off_rounded,
|
||||
@@ -282,38 +287,49 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
||||
List<Widget> _theaterBlocks(AppLocalizations l10n) {
|
||||
final dramas = theater.dramas;
|
||||
return [
|
||||
_toolbar(),
|
||||
SliverToBoxAdapter(child: _toolbar()),
|
||||
if (dramas.isEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 40),
|
||||
child: EmptyState(
|
||||
key: const Key('discover-empty'),
|
||||
icon: Icons.movie_filter_outlined,
|
||||
title: l10n.noStories,
|
||||
subtitle: l10n.emptyHint,
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 40),
|
||||
child: EmptyState(
|
||||
key: const Key('discover-empty'),
|
||||
icon: Icons.movie_filter_outlined,
|
||||
title: l10n.noStories,
|
||||
subtitle: l10n.emptyHint,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
DramaGrid(l10n: l10n, dramas: dramas, onOpen: _openDrama),
|
||||
SliverDramaGrid(
|
||||
key: const Key('home-all-dramas-grid'),
|
||||
l10n: l10n,
|
||||
dramas: dramas,
|
||||
onOpen: _openDrama,
|
||||
),
|
||||
if (theater.loadingMore)
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 20),
|
||||
child: Center(
|
||||
child: SizedBox.square(
|
||||
key: Key('theater-load-more'),
|
||||
dimension: 22,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
const SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 20),
|
||||
child: Center(
|
||||
child: SizedBox.square(
|
||||
key: Key('theater-load-more'),
|
||||
dimension: 22,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else if (dramas.isNotEmpty && !theater.hasMore)
|
||||
Padding(
|
||||
key: const Key('paged-list-no-more'),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Text(
|
||||
l10n.noMoreItems,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(color: AppColors.textHint, fontSize: 12),
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
key: const Key('paged-list-no-more'),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Text(
|
||||
l10n.noMoreItems,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(color: AppColors.textHint, fontSize: 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
@@ -401,6 +417,8 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
||||
Navigator.of(context).push<void>(MaterialPageRoute(builder: (_) => page));
|
||||
}
|
||||
|
||||
Widget _sliverBlock(Widget child) => SliverToBoxAdapter(child: _block(child));
|
||||
|
||||
Widget _block(Widget child) => ConstrainedBox(
|
||||
constraints: const BoxConstraints(minHeight: 280),
|
||||
child: Center(child: child),
|
||||
|
||||
Reference in new issue
Block a user