mobile_bottom_navigation_bar.dart 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import 'package:appflowy/generated/flowy_svgs.g.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:go_router/go_router.dart';
  4. /// Builds the "shell" for the app by building a Scaffold with a
  5. /// BottomNavigationBar, where [child] is placed in the body of the Scaffold.
  6. class MobileBottomNavigationBar extends StatelessWidget {
  7. /// Constructs an [MobileBottomNavigationBar].
  8. const MobileBottomNavigationBar({
  9. required this.navigationShell,
  10. super.key,
  11. });
  12. /// The navigation shell and container for the branch Navigators.
  13. final StatefulNavigationShell navigationShell;
  14. @override
  15. Widget build(BuildContext context) {
  16. final style = Theme.of(context);
  17. return Scaffold(
  18. body: navigationShell,
  19. bottomNavigationBar: BottomNavigationBar(
  20. showSelectedLabels: false,
  21. showUnselectedLabels: false,
  22. // Here, the items of BottomNavigationBar are hard coded. In a real
  23. // world scenario, the items would most likely be generated from the
  24. // branches of the shell route, which can be fetched using
  25. // `navigationShell.route.branches`.
  26. type: BottomNavigationBarType.fixed,
  27. items: <BottomNavigationBarItem>[
  28. BottomNavigationBarItem(
  29. // There is no text shown on the bottom navigation bar, but Exception will be thrown if label is null here.
  30. label: 'home',
  31. icon: const FlowySvg(FlowySvgs.m_home_unselected_lg),
  32. activeIcon: FlowySvg(
  33. FlowySvgs.m_home_selected_lg,
  34. color: style.colorScheme.primary,
  35. ),
  36. ),
  37. const BottomNavigationBarItem(
  38. label: 'favorite',
  39. icon: FlowySvg(FlowySvgs.m_favorite_unselected_lg),
  40. activeIcon: FlowySvg(
  41. FlowySvgs.m_favorite_selected_lg,
  42. blendMode: null,
  43. ),
  44. ),
  45. const BottomNavigationBarItem(
  46. label: 'add',
  47. icon: FlowySvg(
  48. FlowySvgs.m_add_circle_xl,
  49. blendMode: null,
  50. ),
  51. ),
  52. BottomNavigationBarItem(
  53. label: 'search',
  54. icon: const FlowySvg(FlowySvgs.m_search_lg),
  55. activeIcon: FlowySvg(
  56. FlowySvgs.m_search_lg,
  57. color: style.colorScheme.primary,
  58. ),
  59. ),
  60. BottomNavigationBarItem(
  61. label: 'notification',
  62. icon: const FlowySvg(FlowySvgs.m_notification_unselected_lg),
  63. activeIcon: FlowySvg(
  64. FlowySvgs.m_notification_selected_lg,
  65. color: style.colorScheme.primary,
  66. ),
  67. ),
  68. ],
  69. currentIndex: navigationShell.currentIndex,
  70. onTap: (int bottomBarIndex) => _onTap(context, bottomBarIndex),
  71. ),
  72. );
  73. }
  74. /// Navigate to the current location of the branch at the provided index when
  75. /// tapping an item in the BottomNavigationBar.
  76. void _onTap(BuildContext context, int bottomBarIndex) {
  77. // When navigating to a new branch, it's recommended to use the goBranch
  78. // method, as doing so makes sure the last navigation state of the
  79. // Navigator for the branch is restored.
  80. navigationShell.goBranch(
  81. bottomBarIndex,
  82. // A common pattern when using bottom navigation bars is to support
  83. // navigating to the initial location when tapping the item that is
  84. // already active. This example demonstrates how to support this behavior,
  85. // using the initialLocation parameter of goBranch.
  86. initialLocation: bottomBarIndex == navigationShell.currentIndex,
  87. );
  88. }
  89. }