Home > Back-end >  how to make bottomNav appears on screens that are not defined in it? (Flutter)
how to make bottomNav appears on screens that are not defined in it? (Flutter)

Time:06-12

I've created a BottomNav that has 4 buttons and it navigates fine between them. But i want this BottomNav to be visible in all screens of the app (those screens that are not directly attached to the BottomNav).

How can I approach such a thing?

here's my BottomNav code to be clear:

int _selectedIndex = 0; 
//list of widgets that already exist on the bottomNav
  static List<Widget> _screens = <Widget>[
    PermissionsRequestScreen(),
    HomeScreen(title: 'Home'),
    NoticesScreen(),
    ProfileScreen(),
    MoreScreen(),
  ];
////////////////////////
// bottom nav bar navigator function
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
/////////////////////
@override
  Widget build(BuildContext context) {
    return Scaffold(
      // appBar: AppBar(),
      body: Center(
        child: _screens.elementAt(_selectedIndex),
      ),

      //bottomNavBar
      bottomNavigationBar: createBottomNavBar(),

    );
  }

///////////////////

// bottom navigation Bar
  Widget createBottomNavBar() {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [primaryColor, secondaryColor],
          stops: [8, 8],
        ),
      ),
      child: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
        backgroundColor: Colors.transparent,
        iconSize: 22,
        selectedItemColor: Colors.white,
        unselectedItemColor: Colors.white24,
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.info),
            label: 'Notices',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.more_horiz),
            label: 'More',
          ),
        ],
        enableFeedback: true,
      ),
    );
  }

I've tried to use pushReplacement when moving from the bottomNav screen to the next one but it doesn't work.

So, i.e.: How to keep the BottomNav visible in the screens that aren't directly attached to the BottomNav??

CodePudding user response:

You can use PageView to achieve your goal.

Example PageView:

class MainPageView extends StatelessWidget {
  MainPageView({Key? key}) : super(key: key);

  final pageController = PageController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SizedBox.expand(
        child: PageView(
          controller: pageController,
          physics: const NeverScrollableScrollPhysics(),
          onPageChanged: (_){},
          children: const <Widget>[
            FirstView(),
            SecondView(),
            ThirdView(),
            FourthView(),
          ],
        ),
      ),
      bottomNavigationBar: const NavigationBarView(),
    );
  }
}

You need to create PageController to change the page on the screen when an item from BottomNavigation is selected.

If you have further questions, please don't hesitate to write in the comments.

CodePudding user response:

You can try persistent_bottom_nav_bar package. It is easy to use and also has 20 different style.

If you want to have your own style for the navigation bar, follow these steps

Here is an example of implementation;

class _PersistentNavBarState extends State<PersistentNavBar> {
  late PersistentTabController _controller;

  @override
  void initState() {
    _controller = PersistentTabController(initialIndex: 0);
    super.initState();
  }

  List<Widget> _buildScreens() {
    return [
      HomeScreen(title: 'Home'),
      NoticesScreen(),
      ProfileScreen(),
      MoreScreen(),
    ];
  }

  List<PersistentBottomNavBarItem> _navBarsItems() {
    return [
      PersistentBottomNavBarItem(
        icon: Icon(Icons.home),
        title: ('Home'),
        activeColorPrimary: CupertinoColors.activeBlue,
        inactiveColorPrimary: CupertinoColors.systemGrey,
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.info),
        title: ('Notices'),
        activeColorPrimary: CupertinoColors.activeBlue,
        inactiveColorPrimary: CupertinoColors.systemGrey,
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.person),
        title: ('Profile'),
        activeColorPrimary: CupertinoColors.activeBlue,
        inactiveColorPrimary: CupertinoColors.systemGrey,
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.more_horiz),
        title: ('More'),
        activeColorPrimary: CupertinoColors.activeBlue,
        inactiveColorPrimary: CupertinoColors.systemGrey,
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return PersistentTabView(
      context,
      controller: _controller,
      screens: _buildScreens(),
      items: _navBarsItems(),
      confineInSafeArea: true,
      backgroundColor: Colors.white, // Default is Colors.white.
      handleAndroidBackButtonPress: true, // Default is true.
      resizeToAvoidBottomInset:
          true, // This needs to be true if you want to move up the screen when keyboard appears. Default is true.
      stateManagement: true, // Default is true.
      hideNavigationBarWhenKeyboardShows:
          true, // Recommended to set 'resizeToAvoidBottomInset' as true while using this argument. Default is true.
      decoration: NavBarDecoration(
        borderRadius: BorderRadius.circular(10.0),
        colorBehindNavBar: Colors.white,
      ),
      popAllScreensOnTapOfSelectedTab: true,
      popActionScreens: PopActionScreensType.all,
      itemAnimationProperties: ItemAnimationProperties(
        // Navigation Bar's items animation properties.
        duration: Duration(milliseconds: 200),
        curve: Curves.ease,
      ),
      screenTransitionAnimation: ScreenTransitionAnimation(
        // Screen transition animation on change of selected tab.
        animateTabTransition: true,
        curve: Curves.ease,
        duration: Duration(milliseconds: 200),
      ),
      navBarStyle: NavBarStyle
          .neumorphic, // Choose the nav bar style with this property.
    );
  }
}
  • Related