Tartarus
Tartarus

Reputation: 21

Change the body of Scaffold dynamically using a list of Widgets

I have a List of Widgets which should act as the body in the Scaffold Widget(in the Dashboard class) according to the activeIndex in the BottomNavigationBar but the body doesn't update when the activeIndex is changed.

The BottomNavigationBar Code:

class BottomNavBar extends StatefulWidget {
  BottomNavBar({Key? key}) : super(key: key);

  int activeIndex = 1;

  @override
  _BottomNavBarState createState() => _BottomNavBarState();
}

class _BottomNavBarState extends State<BottomNavBar> {
  final Color primaryColor = Color(0xff2FC4B2);
  final Color inactiveIconColor = Colors.white;
  final Color activeIconColor = Colors.blue;

  void setIndex(int index) {
    setState(() {
      widget.activeIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      items: [
        BottomNavigationBarItem(
            icon: Icon(
              Icons.track_changes_outlined,
              color: inactiveIconColor,
            ),
            activeIcon: Icon(
              Icons.track_changes_outlined,
              color: activeIconColor,
            ),
            label: "Track"),
        BottomNavigationBarItem(
            icon: Icon(
              Icons.home_outlined,
              color: inactiveIconColor,
            ),
            activeIcon: Icon(
              Icons.home_outlined,
              color: activeIconColor,
            ),
            label: "Home"),
        BottomNavigationBarItem(
            icon: Icon(
              Icons.settings_outlined,
              color: inactiveIconColor,
            ),
            activeIcon: Icon(
              Icons.settings_outlined,
              color: activeIconColor,
            ),
            label: "Settings")
      ],
      backgroundColor: primaryColor,
      fixedColor: Colors.white,
      showSelectedLabels: false,
      showUnselectedLabels: false,
      currentIndex: widget.activeIndex,
      onTap: setIndex,
    );
  }
}

The Dashboard Code:

class Dashboard extends StatefulWidget {
  final String? userID;
  final String? userName;

  Dashboard(this.userID, this.userName);

  @override
  _DashboardState createState() => _DashboardState();
}

class _DashboardState extends State<Dashboard> {
  BottomNavBar navBar = new BottomNavBar();

  @override
  Widget build(BuildContext context) {
    List<Widget> navBarItems = [Track(), Home(widget.userID, widget.userName)];
    return Scaffold(
      bottomNavigationBar: navBar,
      body: navBarItems.elementAt(navBar.activeIndex),
    );
  }
}

Upvotes: 1

Views: 334

Answers (1)

Vadim Popov
Vadim Popov

Reputation: 772

Working with bar index state should be like that:

class BottomNavBar extends StatefulWidget {

BottomNavBar({Key? key, int initialIndex = 1, required Function onIndexChanged}) : super(key: key);
    
final int initialIndex;
final Function(int) onIndexChanged;
    
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
    
class _BottomNavBarState extends State<BottomNavBar> {
    
  late int activeIndex;
    
  @override
  void initState() {
    super.initState();
    activeIndex = widget.initialIndex;
  }
    
  void setIndex(int _index) {
    setState(() {
      activeIndex = _index;
    });
    widget.onIndexChanged(activeIndex);
  }
    
@override
Widget build(BuildContext context) {
  ///other code
  currentIndex: activeIndex,
  onTap: setIndex,
  ///other code
 }
}

...

class _DashboardState extends State<Dashboard> {

  int currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    List<Widget> navBarItems = [Track(), Home(widget.userID, 
    widget.userName)];
    return Scaffold(
      bottomNavigationBar: BottomNavBar(
        initialIndex: 1,
        onIndexChanged: (int index) {
           setState(() {
             currentIndex = index;
           });
        }
      ),
      body: navBarItems.elementAt(currentIndex),
    );
  }

...

StatefulWidget documentation

Upvotes: 1

Related Questions