Active Tab not staying highlighted with BottomNavigationBar (flips on then back off)

0

I am building a flutter app with several different files so I can piece them together as needed. One of the separate files builds out a BottomNavigationBar. The other files build out the separate pages that the BottomNavigationBar will link to. Navigation works fine, but every time I change screens, the color of the BottomNavigationBar (which should be highlighting the screen that is currently active) is snapping back to the first tab. I am certain the reason for this is that when I click on the BottomNavigationBar, it appropriately routes me to the next view (and in fact I see the new tab highlighted on the old view before going to the next one) and then once on the new page, BottomNavigationBar is being called again, where I am establishing that it start at its home point (the first tab) until further notice. Here is the code for the BottomNavigationBar file:

import 'package:flutter/material.dart';
import 'profile.dart';
import 'search.dart';
import 'favorites.dart';
import 'featured.dart';

class NavBar extends StatefulWidget {
  @override
  NavBarState createState() => NavBarState();
}

 class NavBarState extends State<NavBar>{

 int currentTab = 0;

  FeaturedScreen one;
  SearchScreen two;
  FavoritesScreen three;
  ProfileScreen four;
  List<Widget> pages;
  Widget currentPage;

  @override
  void initState() {
    one = FeaturedScreen();
    two = SearchScreen();
    three = FavoritesScreen();
    four = ProfileScreen();

    pages = [one, two, three, four];

    super.initState();
  } 

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar( 
      type: BottomNavigationBarType.fixed,
      currentIndex: currentTab,
      fixedColor: new Color(0xffffffff).withOpacity(0.5), 
      onTap: (int index) {
        setState((){
          currentTab = index;
          currentPage = pages[index];
        });
        Navigator.push(
          context, 
          new MaterialPageRoute(builder: (context) => currentPage)
        );
      },
      items: <BottomNavigationBarItem>[ 
        BottomNavigationBarItem(
          icon: currentTab==0?Icon( 
            Icons.apps,
            color: Color(0xff70E0EF),
            size: 35.0,
           ):Icon(
            Icons.apps,
            color: Colors.black,
            size: 35.0,
          ),
          title: Text(
            'Collections',
            style: new TextStyle(
              color: Colors.white,
              fontSize: 0.0,
              height: 0.0,
            ),
          ), 
        ),
        BottomNavigationBarItem(
          icon: currentTab==1?Icon(
            Icons.search,
            color: Color(0xff70E0EF),
            size: 35.0,
          ):Icon(
            Icons.search,
            color: Colors.black,
            size: 35.0,
          ),
          title: Text(
            'Search',
            style: new TextStyle(
              color: Colors.white,
              fontSize: 0.0,
              height: 0.0,
            ),
          ),
        ),
        BottomNavigationBarItem(
          icon: currentTab==2?Icon(
            Icons.favorite,
            color: Color(0xff70E0EF),
            size: 35.0,
          ):Icon(
            Icons.favorite,
            color: Colors.black,
            size: 35.0,
          ),
          title: Text(
            'Favorites',
            style: new TextStyle(
              color: Colors.white,
              fontSize: 0.0,
              height: 0.0,
            ),
          ),
        ),
        BottomNavigationBarItem(
          icon: currentTab==3?Icon(
            Icons.person,
            color: Color(0xff70E0EF),
            size: 35.0,
          ):Icon(
            Icons.person,
            color: Colors.black,
            size: 35.0,
          ), 
          title: Text(
            'Profile',
            style: new TextStyle(
              color: Colors.white,
              fontSize: 0.0,
              height: 0.0,
            ),
          ),           
        ),
      ],
    );
  }
}

Each of the four items will load a page that, for now, looks more or less exactly like this:

import 'package:flutter/material.dart';
import 'navbar.dart';

class FeaturedScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Featured(),
      bottomNavigationBar: NavBar(),
    );
  }
}

class Featured extends StatefulWidget {
  @override
  FeaturedState createState() => FeaturedState();
}

class FeaturedState extends State<Featured>{

  @override
  Widget build(BuildContext context) {
    return Scaffold( 
      body: new Stack(
        fit: StackFit.passthrough,
        children: [
          new Container(
            decoration: new BoxDecoration(
              image: new DecorationImage(
                image: new AssetImage('assets/FeaturedBG.png'),
                fit: BoxFit.cover
              ),
            ),
          ),
        ],
      ),
    );
  }
}

How can I make it so that BottomNavigationBar activates correctly per active page?

P.S. Sorry if this was a confusing question. Happy to make a gif of what's happening on request.

dart
flutter

1 Answer

2

In the example code you have posted, each page is getting a new BottomNavigationBar. So when you navigate to it, it will always begin at the initial state. To avoid this problem, you should structure your pages so that there is a single bottom navigation bar that they all share, instead of using the router. You will also need to remove the Scaffold and nav bar from each page.

class MyScreens extends StatefulWidget {
  @override
  MyScreensState createState() => new MyScreensState();
}

class MyScreensState extends State<MyScreens> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: _pages[currentTab], // <- change the widget here
      navBar: new BottomNavigationBar( /* ... */),
    );
  }
}

For more ideas on how to structure a bottom nav bar, check out the example code in the flutter gallery.

answered on Stack Overflow Jul 5, 2018 by Jonah Williams

User contributions licensed under CC BY-SA 3.0