Files
monisuo/flutter_monisuo/lib/ui/pages/main/main_page.dart

142 lines
4.1 KiB
Dart
Raw Normal View History

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<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int _currentIndex = 0;
final List<Widget> _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<Widget> children;
const IndexedStack({
super.key,
required this.index,
required this.children,
});
@override
State<IndexedStack> createState() => _IndexedStackState();
}
class _IndexedStackState extends State<IndexedStack> {
@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(),
);
}
}