1

How to rebuild bottom navigation bar when one of the pages is getting rebuilt?

For example, I have a setState call that rebuilds page, but it does not rebuild navigation bar because it is used as part of bottomNavigationBar property in Scaffold returned from the page:

    return SafeArea(child: Scaffold(
      bottomNavigationBar: CustomBottomNavigationBar(0),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: buttonCards,
      )
    ));

How do I get navigation bar rebuilt?

Edit: here is my CustomBottomNavigationBar implementation for reference:

class CustomBottomNavigationBar extends StatefulWidget {
  
  int _currentIndex = 0;
  
  CustomBottomNavigationBar(this._currentIndex);
  
  @override
  CustomBottomNavigationBarState createState() => CustomBottomNavigationBarState(_currentIndex);

}

class CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> with TickerProviderStateMixin {
  
  int _currentIndex = 0;
  List<_NavigationIconView> _navigationViews;
  
  CustomBottomNavigationBarState(this._currentIndex); 

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (_navigationViews == null) {
      _navigationViews = <_NavigationIconView>[
        _NavigationIconView(
          icon: Icon(Icons.home),
          title: "Home",
          route: HomePage.route,
          vsync: this,
        ) ,
        _NavigationIconView(
          icon: const Icon(Icons.casino),
          title: "Game",
          route: GameStartPage.route,
          vsync: this,
        ),
        _NavigationIconView(
          icon: const Icon(Icons.settings),
          title: "Settings",
          route: SettingsPage.route,
          vsync: this,
        ),
      ];
      
      _navigationViews[_currentIndex].controller.value = 1;
    }
  }
  
  BottomNavigationBar build(BuildContext context) {
    
    var bottomNavigationBarItems = _navigationViews
      .map<BottomNavigationBarItem>((navigationView) => navigationView.item)
      .toList();
    
    return BottomNavigationBar(
      showUnselectedLabels: false,
      items: bottomNavigationBarItems,
      currentIndex: _currentIndex,
      type: BottomNavigationBarType.fixed,
      onTap: (index) {
        setState(() {
          _navigationViews[_currentIndex].controller.reverse();
          _currentIndex = index;
          _navigationViews[_currentIndex].controller.forward();
          Navigator.pushNamed(context, _navigationViews[_currentIndex].route);
        });
      },
      selectedItemColor: Theme
        .of(context)
        .colorScheme
        .primaryLight,
      unselectedItemColor: Theme
        .of(context)
        .colorScheme
        .primaryLight
        .withOpacity(0.38),
    );
  }
  
  @override
  void dispose() {
    for (final view in _navigationViews) {
      view.controller.dispose();
    }
    super.dispose();
  }
}

class _NavigationIconView {
  _NavigationIconView({
    this.title,
    this.icon,
    this.route,
    TickerProvider vsync,
  }) : item = BottomNavigationBarItem(
    icon: icon,
    title: Text(title),
  ),
    controller = AnimationController(
      duration: kThemeAnimationDuration,
      vsync: vsync,
    );
  
  final String title;
  final Widget icon;
  final String route;
  final BottomNavigationBarItem item;
  final AnimationController controller;
}
altern
  • 5,829
  • 5
  • 44
  • 72

1 Answers1

1

You will need to call set state on your CustomBottomNavigationBar because it has its own build method. This is actually a good thing because it is not built each time the parent widget is on a rebuild.

I found an answer here on stackoverflow that you could use to call setstate here

Typically I would recommend using either BLOC pattern or Scoped Model pattern so that you use viewmodels for any logic. When doing it this way I typically use a message bus (I use the flutter library event_bus) to send events to other view models that subscribe for the event and may need to update their view and call a form of setState. I can provider an example of this as well if needed.

rleffler
  • 430
  • 6
  • 15