Files
video/app/lib/screens/home/home_shell.dart
T
2026-10-17 19:04:05 +08:00

98 lines
3.2 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/theme/app_theme.dart';
import '../../providers/feed_provider.dart';
import '../../screens/category/category_screen.dart';
import '../../screens/feed/feed_screen.dart';
import '../../screens/notification/notifications_screen.dart';
import '../../screens/profile/mine_screen.dart';
import '../../screens/upload/upload_screen.dart';
/// 首页壳:底部 Tab(首页/分类/发布/消息/我的),02-技术文档信息架构
/// IndexedStack 保活各 Tab 状态(Feed 播放器池 / 分类滚动位置 / 上传流程不被销毁)
class HomeShell extends ConsumerStatefulWidget {
const HomeShell({super.key});
@override
ConsumerState<HomeShell> createState() => _HomeShellState();
}
class _HomeShellState extends ConsumerState<HomeShell> {
int _index = 0;
/// Feed 三种策略的 provider keys(切 Tab 时用于暂停/恢复播放器池)
static const _feedStrategies = FeedStrategy.values;
void _onTabSelected(int i) {
if (i == _index) return;
// 切到非首页:挂起所有 Feed 策略的播放器池(IndexedStack 保活,
// suspend 会同时阻止在途 open 完成后自动播放,杜绝后台幽灵声)
if (i != 0) {
for (final s in _feedStrategies) {
ref.read(feedProvider(s).notifier).pool.suspend();
}
}
ref.read(feedTabVisibleProvider.notifier).state = i == 0;
setState(() => _index = i);
// 切回首页:只恢复当前选中策略的池(其余保持挂起)
if (i == 0) {
final active = ref.read(activeFeedStrategyProvider);
final notifier = ref.read(feedProvider(active).notifier);
unawaited(() async {
await notifier.pool.resume();
// 兜底:挂起期间首屏 bind 可能尚未发生,补一次当前页绑定播放
await notifier.rebindCurrent();
}());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _index,
children: const [
FeedScreen(),
CategoryScreen(),
UploadScreen(),
NotificationsScreen(),
MineScreen(),
],
),
bottomNavigationBar: NavigationBar(
height: 60,
backgroundColor: AppColors.surface,
indicatorColor: AppColors.primary.withValues(alpha: 0.2),
selectedIndex: _index,
onDestinationSelected: _onTabSelected,
destinations: const [
NavigationDestination(
icon: Icon(Icons.home_outlined),
selectedIcon: Icon(Icons.home, color: AppColors.primary),
label: '首页',
),
NavigationDestination(
icon: Icon(Icons.grid_view_outlined),
label: '分类',
),
NavigationDestination(
icon: Icon(Icons.add_box_outlined),
label: '发布',
),
NavigationDestination(
icon: Icon(Icons.notifications_none),
label: '消息',
),
NavigationDestination(
icon: Icon(Icons.person_outline),
label: '我的',
),
],
),
);
}
}