import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/app_provider.dart'; import '../utils/user_prefs.dart'; import '../utils/responsive.dart'; import '../widgets/custom_drawer.dart'; import '../widgets/bottom_nav_bar.dart'; import '../widgets/add_sheet.dart'; import 'main_content_page.dart'; import 'profile_page.dart'; /// 主页 - 包含底部导航,可切换主页/我的 class HomePage extends StatefulWidget { const HomePage({super.key}); @override State createState() => _HomePageState(); } class _HomePageState extends State { final PageController _pageController = PageController(); bool _isSwitchingPage = false; int _lastNavIndex = 0; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _lastNavIndex = context.read().bottomNavIndex; }); } @override void dispose() { _pageController.dispose(); super.dispose(); } void _onNavIndexChanged(AppProvider provider) { final currentPage = provider.bottomNavIndex == 0 ? 0 : 1; if (currentPage == _lastNavIndex) return; _lastNavIndex = currentPage; if (!_pageController.hasClients) return; if (_pageController.page?.round() == currentPage) return; WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; _isSwitchingPage = true; _pageController.jumpToPage(currentPage); Future.delayed(const Duration(milliseconds: 300), () { if (mounted) { _isSwitchingPage = false; provider.setBottomNavVisible(true); } }); }); } @override Widget build(BuildContext context) { if (Breakpoint.isTablet(context)) { return _buildTabletLayout(context); } return _buildPhoneLayout(context); } Widget _buildTabletLayout(BuildContext context) { final colors = Theme.of(context).colorScheme; return Consumer( builder: (context, provider, child) { _onNavIndexChanged(provider); return Scaffold( body: Row( children: [ SizedBox( width: 260, child: Material( color: colors.surfaceContainerHigh, child: const CustomDrawer(embedded: true), ), ), NavigationRail( selectedIndex: provider.bottomNavIndex == 0 ? 0 : 1, backgroundColor: colors.surface, labelType: NavigationRailLabelType.all, leading: Padding( padding: const EdgeInsets.only(top: 8, bottom: 12), child: FloatingActionButton.small( onPressed: () => showAddSheet(context, provider), child: const Icon(Icons.add), ), ), onDestinationSelected: (index) { provider.setBottomNavIndex(index == 0 ? 0 : 2); }, destinations: const [ NavigationRailDestination( icon: Icon(Icons.home_outlined), selectedIcon: Icon(Icons.home), label: Text('首页'), ), NavigationRailDestination( icon: Icon(Icons.person_outline), selectedIcon: Icon(Icons.person), label: Text('我的'), ), ], ), Expanded(child: _buildPageView(provider)), ], ), ); }, ); } Widget _buildPhoneLayout(BuildContext context) { return Scaffold( drawer: context.watch().bottomNavIndex != 1 ? const CustomDrawer() : null, body: Consumer( builder: (context, provider, child) { _onNavIndexChanged(provider); return NotificationListener( onNotification: (notification) { if (_isSwitchingPage) return false; if (notification is ScrollUpdateNotification) { final delta = notification.scrollDelta; if (delta != null && delta.abs() > 2) { final userPrefs = UserPrefs(); if (!userPrefs.hideBottomNavOnScroll) return false; if (delta < 0) { provider.setBottomNavVisible(true); } else { provider.setBottomNavVisible(false); } } } return false; }, child: Stack( children: [ _buildPageView(provider), // 底部导航栏区域 Positioned( left: 0, right: 0, bottom: 0, child: AnimatedSlide( offset: provider.bottomNavVisible ? Offset.zero : const Offset(-1, 0), duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, child: const CustomBottomNavBar(), ), ), if (!provider.bottomNavVisible) Positioned( left: 0, bottom: MediaQuery.of(context).padding.bottom + 20, child: GestureDetector( onTap: () => provider.setBottomNavVisible(true), onHorizontalDragEnd: (details) { if (details.primaryVelocity != null && details.primaryVelocity! > 0) { provider.setBottomNavVisible(true); } }, child: Container( width: 44, height: 56, decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.horizontal( right: Radius.circular(28)), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.08), blurRadius: 20, offset: const Offset(0, 4), spreadRadius: 0, ), ], ), child: Center( child: Icon( Icons.chevron_right, color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.4), size: 24, ), ), ), ), ), ], ), ); }, ), ); } Widget _buildPageView(AppProvider provider) { return PageView( controller: _pageController, physics: const NeverScrollableScrollPhysics(), onPageChanged: (index) { if (index == 0) { provider.setBottomNavIndex(0); } else if (index == 1) { provider.setBottomNavIndex(2); } }, children: [ const MainContentPage(), const ProfilePage(), ], ); } }