126 lines
2.9 KiB
Dart
126 lines
2.9 KiB
Dart
import 'package:flutter/material.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) {
|
|
return DecoratedBox(
|
|
decoration: const BoxDecoration(
|
|
color: YantingColors.background,
|
|
border: Border(top: BorderSide(color: YantingColors.border)),
|
|
),
|
|
child: SizedBox(
|
|
height: YantingSpacing.tabBarHeight,
|
|
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 color = selected
|
|
? YantingColors.foreground
|
|
: YantingColors.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,
|
|
),
|
|
];
|