import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import '../home/home_page.dart'; import '../market/market_page.dart'; import '../trade/trade_page.dart'; import '../asset/asset_page.dart'; import '../mine/mine_page.dart'; /// 主页面(使用 shadcn_ui 风格) class MainPage extends StatefulWidget { const MainPage({super.key}); @override State createState() => _MainPageState(); } class _MainPageState extends State { int _currentIndex = 0; final List _pages = [ const HomePage(), const MarketPage(), const TradePage(), const AssetPage(), const MinePage(), ]; final List<_TabItem> _tabs = [ _TabItem('首页', LucideIcons.house, LucideIcons.house), _TabItem('行情', LucideIcons.trendingUp, LucideIcons.trendingUp), _TabItem('交易', LucideIcons.arrowLeftRight, LucideIcons.arrowLeftRight), _TabItem('资产', LucideIcons.wallet, LucideIcons.wallet), _TabItem('我的', LucideIcons.user, LucideIcons.user), ]; @override Widget build(BuildContext context) { final theme = ShadTheme.of(context); return Scaffold( body: IndexedStack( index: _currentIndex, children: _pages, ), bottomNavigationBar: Container( decoration: BoxDecoration( color: theme.colorScheme.background, border: Border( top: BorderSide(color: theme.colorScheme.border), ), ), child: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: _tabs.asMap().entries.map((entry) { final index = entry.key; final tab = entry.value; final isSelected = index == _currentIndex; return GestureDetector( onTap: () => setState(() => _currentIndex = index), behavior: HitTestBehavior.opaque, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( tab.icon, color: isSelected ? theme.colorScheme.primary : theme.colorScheme.mutedForeground, size: 24, ), const SizedBox(height: 4), Text( tab.label, style: TextStyle( fontSize: 12, color: isSelected ? theme.colorScheme.primary : theme.colorScheme.mutedForeground, fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, ), ), ], ), ), ); }).toList(), ), ), ), ), ); } } class _TabItem { final String label; final IconData icon; final IconData selectedIcon; _TabItem(this.label, this.icon, this.selectedIcon); } /// IndexedStack 用于保持页面状态 class IndexedStack extends StatefulWidget { final int index; final List children; const IndexedStack({ super.key, required this.index, required this.children, }); @override State createState() => _IndexedStackState(); } class _IndexedStackState extends State { @override Widget build(BuildContext context) { return Stack( children: widget.children.asMap().entries.map((entry) { return Positioned.fill( child: Offstage( offstage: entry.key != widget.index, child: TickerMode( enabled: entry.key == widget.index, child: entry.value, ), ), ); }).toList(), ); } }