Home > Enterprise >  How to change the BottomNavigationBar after a Navigator.push?
How to change the BottomNavigationBar after a Navigator.push?

Time:08-11

I would like to set a new BottomNavigationBar after i've clicked on one of my ListTile. Right now, i am getting two BottomNavigationbar after I've clicked on one of them.

Below is my code where I setup the first bar:

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

  @override
  State<CoachNav> createState() => _CoachNavState();
}

class _CoachNavState extends State<CoachNav> {
  int _selectedIndex = 0;

  final List<Widget> _widgetOptions = <Widget>[
    const TeamListView(),
    const SettingsFormView(),
  ];

  Widget? _onItemTap(int index) {
    setState(() {
      _selectedIndex = index;
    });
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.groups),
            label: "Mes équipes",
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.settings), label: "Paramètres"),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTap,
      ),
    );
  }
}

Then, there is the code where I setup the second bar:

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

  @override
  State<TeamNav> createState() => _TeamNavState();
}

class _TeamNavState extends State<TeamNav> {
  int _selectedIndex = 0;

  final List<Widget> _widgetOptions = <Widget>[
    const PlayersListView(),
    const GamesListView(),
  ];

  Widget? _onItemTap(int index) {
    setState(() {
      _selectedIndex = index;
    });
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.group),
            label: "Mes joueurs",
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.sports_basketball), label: "Mes matchs"),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTap,
      ),
    );
  }
}

Here are two screenshots of what is happening

First Bar

Second Bar

---------------- EDIT ----------------------

This is what I get when I make the _widgetOptions texts

I got the first bar... whith the content from where the second bar should Appear

this is the snippet of the code I got as answer below:

    lass App extends StatelessWidget {
      const App({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home: CoachNav());
      }
    }
    
    class TeamNav extends StatefulWidget {
      const TeamNav({Key? key}) : super(key: key);
    
      @override
      State<TeamNav> createState() => _TeamNavState();
    }
    
    class _TeamNavState extends State<TeamNav> {
      int _selectedIndex = 0;
    
      final List<Widget> _widgetOptions = <Widget>[
        Text("PlayersListView"),
        Text("PlayersListView"),
      ];
    
      Widget? _onItemTap(int index) {
        setState(() {
          _selectedIndex = index;
        });
        return null;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
     /*     floatingActionButton: FloatingActionButton(onPressed: () {
            Navigator.of(context).push(MaterialPageRoute(
              builder: (context) => CoachNav(),
            ));
          }),*/
          body: Container(
            child: _widgetOptions.elementAt(_selectedIndex),
          ),
          bottomNavigationBar: BottomNavigationBar(
            items: const [
              BottomNavigationBarItem(
                icon: Icon(Icons.group),
                label: "Mes joueurs",
              ),
              BottomNavigationBarItem(
                  icon: Icon(Icons.sports_basketball), label: "Mes matchs"),
            ],
            currentIndex: _selectedIndex,
            onTap: _onItemTap,
          ),
        );
      }
    }
    
    class CoachNav extends StatefulWidget {
      const CoachNav({Key? key}) : super(key: key);
    
      @override
      State<CoachNav> createState() => _CoachNavState();
    }
    
    class _CoachNavState extends State<CoachNav> {
      int _selectedIndex = 0;
    
      final List<Widget> _widgetOptions = <Widget>[
        Text("PlayersListView"),
        Text("PlayersListView"),
      ];
    
      Widget? _onItemTap(int index) {
        setState(() {
          _selectedIndex = index;
        });
        return null;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(
            child: _widgetOptions.elementAt(_selectedIndex),
          ),
          //floatingActionButton: FloatingActionButton(onPressed: () {}),
          bottomNavigationBar: BottomNavigationBar(
            items: const [
              BottomNavigationBarItem(
                icon: Icon(Icons.groups),
                label: "Mes équipes",
              ),
              BottomNavigationBarItem(
                  icon: Icon(Icons.settings), label: "Paramètres"),
            ],
            currentIndex: _selectedIndex,
            onTap: _onItemTap,
          ),
        );
      }
    }
This is the code that have the text shown in the third screenshot.
    class PlayersListView extends StatelessWidget {
      const PlayersListView({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(body: Text("Playerslist"),);
      }
    }

CodePudding user response:

I think you have a design problem.

In your case, the best way is this one, i think.

When you tap on a tile you should fix a flag and rebuild your page instead of navigating to a new route.

Then, when building your BottomNavigationBarItemlist check the flag and add or remove BottomNavigationBarItem as you need.

CodePudding user response:

Remove extra scaffold from _widgetOptions children that contains bottomNavBar. Follow the snippet pattern

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: TeamNav());
  }
}

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

  @override
  State<TeamNav> createState() => _TeamNavState();
}

class _TeamNavState extends State<TeamNav> {
  int _selectedIndex = 0;

  final List<Widget> _widgetOptions = <Widget>[
    Text("PlayersListView"),
    Text(" GamesListView()"),
  ];

  Widget? _onItemTap(int index) {
    setState(() {
      _selectedIndex = index;
    });
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(onPressed: () {
        Navigator.of(context).push(MaterialPageRoute(
          builder: (context) => CoachNav(),
        ));
      }),
      body: Container(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.group),
            label: "Mes joueurs",
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.sports_basketball), label: "Mes matchs"),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTap,
      ),
    );
  }
}

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

  @override
  State<CoachNav> createState() => _CoachNavState();
}

class _CoachNavState extends State<CoachNav> {
  int _selectedIndex = 0;

  final List<Widget> _widgetOptions = <Widget>[
    Text("TeamListView"),
    Text("SettingsFormView"),
  ];

  Widget? _onItemTap(int index) {
    setState(() {
      _selectedIndex = index;
    });
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      floatingActionButton: FloatingActionButton(onPressed: () {}),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.groups),
            label: "Mes équipes",
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.settings), label: "Paramètres"),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTap,
      ),
    );
  }
}
  • Related