skip to Main Content

so i just made a bottom navigation bar. the problem is my bottom navbar is gone when i push to other page like the whole page is replaced.

i’ve searching any tutorial mostly just showing how to make the bottom navbar but not showing until if we have a button inside "root pages of navigation". (check home_page.dart)

or after inside the bottomnav pages, i shouldnt use the Navigator.push again ?

i’m aware there is a package persistent_bottom_nav_bar_v2, but is this the only way ?

i also made other project with basic navbar using plain setstate, but same result.
is there anything i missed or using the package is the only way ? thank you.

class MainWrapperController extends GetxController {
  final Rx<int> _selectedIndex = 0.obs;

  int get selectedIndex => _selectedIndex.value;

  void setSelectedIndex(int index) => _selectedIndex.value = index;

  List<NavigationItemModel> navItemModels = [
    NavigationItemModel(
      navigatorKey: GlobalKey<NavigatorState>(),
      title: "Home",
      icon: Icons.home,
      page: const HomePage(),
    ),
    NavigationItemModel(
      navigatorKey: GlobalKey<NavigatorState>(),
      title: "Report",
      icon: Icons.equalizer,
      page: const ReportMenuPage(),
    ),
    NavigationItemModel(
      navigatorKey: GlobalKey<NavigatorState>(),
      title: "Profile",
      icon: Icons.person,
      page: const ProfilePage(),
    ),
  ];
}

main_wrapper.dart

class MainWrapper extends StatefulWidget {
  const MainWrapper({super.key});

  @override
  State<MainWrapper> createState() => _MainWrapperState();
}

class _MainWrapperState extends State<MainWrapper> {
  var mainWrapperController = Get.find<MainWrapperController>();

  @override
  Widget build(BuildContext context) {
    var navPages = mainWrapperController.navItemModels
        .map(
          (item) => Navigator(
            key: item.navigatorKey,
            onGenerateRoute: (setting) {
              return MaterialPageRoute(builder: (context) => item.page);
            },
          ),
        )
        .toList();

    var navItems = mainWrapperController.navItemModels
        .map((item) =>
            BottomNavigationBarItem(icon: Icon(item.icon), label: item.title))
        .toList();

    return PopScope(
      canPop: false,
      onPopInvoked: (state) {},
      child: Scaffold(
        body: Obx(
          () => IndexedStack(
            index: mainWrapperController.selectedIndex,
            children: navPages,
          ),
        ),
        bottomNavigationBar: Obx(
          () => BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedFontSize: 0,
            unselectedFontSize: 0,
            backgroundColor: Colors.white,
            selectedItemColor: ColorConstant.selectedIcon,
            showSelectedLabels: false,
            showUnselectedLabels: false,
            items: navItems,
            iconSize: 36,
            onTap: (index) => mainWrapperController.setSelectedIndex(index),
            currentIndex: mainWrapperController.selectedIndex,
          ),
        ),
      ),
    );
  }
}

home_page.dart

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: ColorConstant.background,
        body: Column(
          children: [
            // here when i push, the whole page is changed not persisting bottom navbar
            SimpleButtonWidget(
              onPressed: () => Get.to(const NextPage()),
              text: 'Click Me',
            )
          ],
        ));
  }
}

next_page.dart

class NextPage extends StatelessWidget {
  const NextPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Text("HELLO FROM NEXT PAGE");
  }
}

expecting the bottom navbar not disappear when navigating from inside the "root pages of navigation" (see home_page.dart).

2

Answers


  1. you are implementing it wrong

    try this example

    class Home extends StatefulWidget {
    
       @override
      State<Home> createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      int currentIndex = 0;
    
      @override
      Widget build(BuildContext context) {
    return Scaffold(
        bottomNavigationBar: NavigationBarTheme(
          data: NavigationBarThemeData(
            labelTextStyle: MaterialStateProperty.resolveWith<TextStyle>(
              (Set<MaterialState> states) =>
                  states.contains(MaterialState.selected)
                      ? const TextStyle(
                          color: Color(0xFFBA172F),
                        )
                      : const TextStyle(color: Colors.black),
            ),
          ),
          child: NavigationBar(
            height: 60,
            onDestinationSelected: (value) {
              setState(() {
                currentIndex = value;
              });
            },
            selectedIndex: currentIndex,
            indicatorColor: const Color.fromARGB(30, 255, 82, 82),
            destinations: [
              NavigationDestination(
                icon: Icon(
                  Icons.home_outlined,
                  color: currentIndex == 0 ? const Color(0xFFBA172F) : null,
                ),
                label: 'Home',
              ),
              NavigationDestination(
                  icon: Icon(
                    Icons.grid_view_outlined,
                    color: currentIndex == 1 ? const Color(0xFFBA172F) : null,
                  ),
                  label: 'Categories'),
              NavigationDestination(
                  icon: Icon(
                    Icons.whatshot_outlined,
                    color: currentIndex == 2 ? const Color(0xFFBA172F) : null,
                  ),
                  tooltip: 'Sizzling Hot Offers',
                  label: 'Trending'),
              NavigationDestination(
                  //show badge only when something is selected //here temporary some bool used.
                  icon: isWideScreen(context)
                      ? Icon(
                          Icons.favorite,
                          color: currentIndex == 3
                              ? const Color(0xFFBA172F)
                              : null,
                        )
                      : Badge(
                          backgroundColor:
                              const Color.fromARGB(255, 238, 255, 55),
                          label: const Text(
                            ' 1 ',
                            style: TextStyle(
                                color: Color(0xFFBA172F),
                                fontWeight: FontWeight.bold),
                          ),
                          child: Icon(
                            Icons.favorite,
                            color: currentIndex == 3
                                ? const Color(0xFFBA172F)
                                : null,
                          ),
                        ),
                  label: 'Favorites'),
              NavigationDestination(
                icon: Icon(
                  Icons.person,
                  color: currentIndex == 4 ? Colors.red : null,
                ),
                label: 'Account',
              ),
            ],
          ),
        ),
        body: <Widget>[
         const Screen0(),
          const Screen1(),
          const Screen2(),
          const Screen3(),
          const Screen4(),
        ][currentIndex],
      ),
    );
    

    }
    }

    Login or Signup to reply.
  2. It seems like you’re building a Flutter app with nested navigation. you can try following steps first create stateful class and name it HomeIndex.this code sets up a navigation system using Flutter’s Navigator widget,we can use Navigator to call sub navigations where routes are dynamically generated based on route settings. Depending on the route, different widgets (HomePage or NextPage) are displayed.

    create global navigator keys to your main screens

    final GlobalKey<NavigatorState> homeNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'homeNavKey');
    final GlobalKey<NavigatorState> ReportNavKey = GlobalKey<NavigatorState>(debugLabel: 'ReportNavKey');
    final GlobalKey<NavigatorState> ProfileNavKey = GlobalKey<NavigatorState>(debugLabel: 'profileNavKey'); 
    

    create HomeIndex class:

    class HomeIndex extends StatefulWidget {
      @override
      _HomeIndexState createState() => _HomeIndexState();
    }
    
    class _HomeIndexState extends State<HomeIndex> {
      final _homePage = const HomePage();
      final _nextPage = const NextPage();
      @override
      Widget build(BuildContext context) {
        return Navigator(
          key:homeNavigatorKey //add global navigator key 
          onGenerateRoute: (RouteSettings settings) {
            return MaterialPageRoute(
              settings: settings,
              builder: (BuildContext context) {
                switch (settings.name) {
                  case '/':
                    return _homePage;
                  case '/next_page':
                    return _nextPage;
                  default:
                    throw Exception("Unknown route: ${settings.name}");
                }
              },
            );
          },
        );
      }
    }
    

    after change your MainWrapperController like this:

    List<NavigationItemModel> navItemModels = [
        NavigationItemModel(
          navigatorKey: GlobalKey<NavigatorState>(),
          title: "Home",
          icon: Icons.home,
          page: const HomeIndex(), //change this
        ),
    

    you navigate to the Nextpage set up a named route for the NextPage widget and uses Navigator.pushNamed to navigate to that route when a button is pressed on the HomePage widget.

    class _HomePageState extends State<HomePage> {
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: ColorConstant.background,
          body: Column(
            children: [
              SimpleButtonWidget(
                onPressed: () {
                   homeNavigatorKey.currentState!.pushNamed('/next_page');
                },
                text: 'Click Me',
              )
            ],
          ),
        );
      }
    }
    

    you can do same thing another main screens. thank you

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search