Files
yanting/lib/widgets/bottom_tab_bar.dart
2026-06-05 17:54:46 +08:00

130 lines
3.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../theme/app_icons.dart';
import '../theme/yanting_text.dart';
import '../theme/yanting_tokens.dart';
class BottomTabBarItem {
const BottomTabBarItem({
required this.label,
required this.icon,
required this.selectedIcon,
});
final String label;
final IconData icon;
final IconData selectedIcon;
}
class BottomTabBar extends StatelessWidget {
const BottomTabBar({
required this.items,
required this.selectedIndex,
required this.onSelected,
super.key,
});
final List<BottomTabBarItem> items;
final int selectedIndex;
final ValueChanged<int> onSelected;
@override
Widget build(BuildContext context) {
final colors = ShadTheme.of(context).colorScheme;
return DecoratedBox(
decoration: const BoxDecoration(color: Colors.transparent),
child: SizedBox(
height: YantingSpacing.tabBarHeight,
child: DecoratedBox(
decoration: BoxDecoration(
color: colors.background,
border: Border(top: BorderSide(color: colors.border)),
),
child: Row(
children: [
for (var index = 0; index < items.length; index++)
Expanded(
child: _BottomTabButton(
item: items[index],
selected: index == selectedIndex,
onTap: () => onSelected(index),
),
),
],
),
),
),
);
}
}
class _BottomTabButton extends StatelessWidget {
const _BottomTabButton({
required this.item,
required this.selected,
required this.onTap,
});
final BottomTabBarItem item;
final bool selected;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final colors = ShadTheme.of(context).colorScheme;
final color = selected ? colors.foreground : colors.mutedForeground;
return InkWell(
onTap: onTap,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
selected ? item.selectedIcon : item.icon,
size: 22,
color: color,
),
const SizedBox(height: 4),
Text(
item.label,
style: YantingText.meta.copyWith(
color: color,
fontSize: 11,
letterSpacing: 0,
fontWeight: selected ? FontWeight.w600 : FontWeight.w400,
),
),
],
),
);
}
}
const yantingBottomTabItems = [
BottomTabBarItem(
label: '推荐',
icon: AppIcons.sparkle,
selectedIcon: AppIcons.sparkleFill,
),
BottomTabBarItem(
label: '研报',
icon: AppIcons.article,
selectedIcon: AppIcons.articleFill,
),
BottomTabBarItem(
label: '机构',
icon: AppIcons.bank,
selectedIcon: AppIcons.bankFill,
),
BottomTabBarItem(
label: '听单',
icon: AppIcons.headphones,
selectedIcon: AppIcons.headphonesFill,
),
BottomTabBarItem(
label: '我的',
icon: AppIcons.user,
selectedIcon: AppIcons.userFill,
),
];