108 lines
3.3 KiB
Dart
108 lines
3.3 KiB
Dart
|
|
import 'package:flutter/material.dart';
|
|||
|
|
import 'package:go_router/go_router.dart';
|
|||
|
|
|
|||
|
|
import '../utils/i10n.dart';
|
|||
|
|
import '../utils/responsive.dart';
|
|||
|
|
|
|||
|
|
/// 底部导航栏(配合 [StatefulShellRoute] 使用)。
|
|||
|
|
///
|
|||
|
|
/// 五个 tab:首页、设备、门店、管理、我的。
|
|||
|
|
class AppBottomNav extends StatelessWidget {
|
|||
|
|
const AppBottomNav({super.key, required this.shell});
|
|||
|
|
|
|||
|
|
/// go_router 的导航壳。
|
|||
|
|
final StatefulNavigationShell shell;
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
Widget build(BuildContext context) {
|
|||
|
|
final t = AppLocalizations.of(context);
|
|||
|
|
|
|||
|
|
final railDestinations = <NavigationRailDestination>[
|
|||
|
|
NavigationRailDestination(
|
|||
|
|
icon: const Icon(Icons.home_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.home),
|
|||
|
|
label: Text(t.home),
|
|||
|
|
),
|
|||
|
|
NavigationRailDestination(
|
|||
|
|
icon: const Icon(Icons.devices_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.devices),
|
|||
|
|
label: Text(t.devices),
|
|||
|
|
),
|
|||
|
|
NavigationRailDestination(
|
|||
|
|
icon: const Icon(Icons.store_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.store),
|
|||
|
|
label: Text(t.stores),
|
|||
|
|
),
|
|||
|
|
NavigationRailDestination(
|
|||
|
|
icon: const Icon(Icons.admin_panel_settings_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.admin_panel_settings),
|
|||
|
|
label: Text(t.admin),
|
|||
|
|
),
|
|||
|
|
NavigationRailDestination(
|
|||
|
|
icon: const Icon(Icons.person_outline),
|
|||
|
|
selectedIcon: const Icon(Icons.person),
|
|||
|
|
label: Text(t.profile),
|
|||
|
|
),
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
void onSelect(int index) => shell.goBranch(
|
|||
|
|
index,
|
|||
|
|
// 点击当前 tab 时回到该分支根路由。
|
|||
|
|
initialLocation: index == shell.currentIndex,
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 横屏:改用左侧 NavigationRail,腾出底部 80dp 纵向空间。
|
|||
|
|
if (context.responsive.isLandscape) {
|
|||
|
|
return Scaffold(
|
|||
|
|
body: Row(
|
|||
|
|
children: [
|
|||
|
|
NavigationRail(
|
|||
|
|
selectedIndex: shell.currentIndex,
|
|||
|
|
onDestinationSelected: onSelect,
|
|||
|
|
labelType: NavigationRailLabelType.all,
|
|||
|
|
destinations: railDestinations,
|
|||
|
|
),
|
|||
|
|
const VerticalDivider(width: 1, thickness: 1),
|
|||
|
|
Expanded(child: shell),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Scaffold(
|
|||
|
|
body: shell,
|
|||
|
|
bottomNavigationBar: NavigationBar(
|
|||
|
|
selectedIndex: shell.currentIndex,
|
|||
|
|
onDestinationSelected: onSelect,
|
|||
|
|
destinations: [
|
|||
|
|
NavigationDestination(
|
|||
|
|
icon: const Icon(Icons.home_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.home),
|
|||
|
|
label: t.home,
|
|||
|
|
),
|
|||
|
|
NavigationDestination(
|
|||
|
|
icon: const Icon(Icons.devices_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.devices),
|
|||
|
|
label: t.devices,
|
|||
|
|
),
|
|||
|
|
NavigationDestination(
|
|||
|
|
icon: const Icon(Icons.store_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.store),
|
|||
|
|
label: t.stores,
|
|||
|
|
),
|
|||
|
|
NavigationDestination(
|
|||
|
|
icon: const Icon(Icons.admin_panel_settings_outlined),
|
|||
|
|
selectedIcon: const Icon(Icons.admin_panel_settings),
|
|||
|
|
label: t.admin,
|
|||
|
|
),
|
|||
|
|
NavigationDestination(
|
|||
|
|
icon: const Icon(Icons.person_outline),
|
|||
|
|
selectedIcon: const Icon(Icons.person),
|
|||
|
|
label: t.profile,
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|