fix(flutter): 首页 feed 顶栏固定悬浮

This commit is contained in:
Zhou Weidong committed 2026-10-20 14:46:08 +08:00
1 parent 1cb4c56261
commit 9175a7f253
6 files changed
+341 -345

No files matched your search

+8 -109
View File
@@ -15,12 +15,6 @@ part 'home_feed_overlay_parts.dart';
const Color _overlayPill = Color(0x66000000);
const Color _fullBarBackground = Color(0x4D000000);
const double _topIconSize = 36;
const double _topIconGlyph = 22;
const double _tabGap = 22;
const double _tabFontSize = 15;
const double _underlineWidth = 18;
const double _underlineHeight = 2;
const double _titleFontSize = 17;
const double _metaFontSize = 12;
const double _tagFontSize = 11;
@@ -33,7 +27,7 @@ const List<Shadow> _boostTextShadows = [
const int _maxTags = 4;
final RegExp _tagSplitter = RegExp(r'[,/、·]');
/// 首页沉浸式 feed 浮层:顶部频道 tab、右侧互动栏、底部信息与整集进度条。
/// 首页沉浸式 feed 浮层:手势层、右侧互动栏、底部信息与整集进度条。
class HomeFeedOverlay extends StatefulWidget {
const HomeFeedOverlay({
super.key,
@@ -49,23 +43,18 @@ class HomeFeedOverlay extends StatefulWidget {
required this.onSave,
required this.onComments,
required this.onShare,
required this.onEpisodes,
required this.onDetail,
required this.onOpenFullPlayer,
required this.onRefreshFeed,
required this.onDownload,
required this.onClear,
required this.onSearch,
required this.onMore,
required this.onTogglePlay,
required this.onBoostStart,
required this.onBoostEnd,
this.onScrubStart,
this.onSeek,
required this.onMore,
this.likeCount,
this.favoriteCount,
this.commentCount,
this.authorNote = '',
this.onScrubStart,
this.onSeek,
});
final AppLocalizations l10n;
@@ -84,28 +73,20 @@ class HomeFeedOverlay extends StatefulWidget {
final VoidCallback onSave;
final VoidCallback onComments;
final VoidCallback onShare;
final VoidCallback onEpisodes;
final VoidCallback onDetail;
final VoidCallback onOpenFullPlayer;
final Future<bool> Function() onRefreshFeed;
final VoidCallback onDownload;
final VoidCallback onClear;
final VoidCallback onSearch;
final VoidCallback onMore;
final VoidCallback onTogglePlay;
final VoidCallback? onScrubStart;
final ValueChanged<Duration>? onSeek;
final VoidCallback onBoostStart;
final VoidCallback onBoostEnd;
final VoidCallback onMore;
final VoidCallback? onScrubStart;
final ValueChanged<Duration>? onSeek;
@override
State<HomeFeedOverlay> createState() => _HomeFeedOverlayState();
}
class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
_FeedTab _tab = _FeedTab.recommend;
bool _refreshing = false;
@override
Widget build(BuildContext context) {
return SafeArea(
@@ -134,7 +115,6 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
else
Column(
children: [
_header(context),
const Spacer(),
if (widget.visible) _bottomInfo(),
_fullSeriesBar(),
@@ -185,77 +165,6 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
);
}
Future<void> _refresh() async {
if (_refreshing) return;
setState(() => _refreshing = true);
await widget.onRefreshFeed();
if (mounted) setState(() => _refreshing = false);
}
Widget _header(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(8, 6, 8, 4),
child: Row(
children: [
_RefreshButton(
tooltip: widget.l10n.retry,
dimension: _topIconSize,
glyphSize: _topIconGlyph,
refreshing: _refreshing,
onTap: _refresh,
onLongPress: widget.onMore,
),
Expanded(
child: Center(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
for (var index = 0; index < _FeedTab.values.length; index++)
_tabSlot(_FeedTab.values[index], index),
],
),
),
),
),
_TopIconButton(
key: const Key('home-feed-search'),
tooltip: widget.l10n.search,
icon: Icons.search_rounded,
dimension: _topIconSize,
glyphSize: _topIconGlyph,
onPressed: widget.onSearch,
),
],
),
);
}
Widget _tabSlot(_FeedTab tab, int index) {
final item = _FeedTabItem(
tab: tab,
label: tab.label(widget.l10n),
selected: _tab == tab,
fontSize: _tabFontSize,
underlineWidth: _underlineWidth,
underlineHeight: _underlineHeight,
onTap: () => _selectTab(tab),
);
if (index == 0) return item;
return Padding(
padding: const EdgeInsets.only(left: _tabGap),
child: item,
);
}
void _selectTab(_FeedTab tab) {
if (tab.comingSoon) {
_showComingSoon();
return;
}
setState(() => _tab = tab);
}
Widget _rail() {
return InteractionRail(
items: [
@@ -377,11 +286,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
),
),
),
const Icon(
Icons.chevron_right_rounded,
color: Colors.white,
size: 20,
),
const Icon(Icons.chevron_right_rounded, color: Colors.white, size: 20),
],
),
);
@@ -494,10 +399,4 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
),
);
}
void _showComingSoon() {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(widget.l10n.comingSoon)));
}
}