Flutter - Multi Page Navigation using bottom navigation bar icons

TJMitch95 picture TJMitch95 · Aug 6, 2020 · Viewed 10.5k times · Source

I'm trying to navigate to different pages within my app using the icons in my bottom navigation bar. I have tried many tutorials and can't seem to work out the best way to achieve this. I have created my Homepage (code below) and 2 additional pages, Inbox and Signin, both return simple scaffolds.

Firstly i'm interested to know if this is the best way to do what i'm trying to achieve and second, how can my code be altered to allow me to navigate to different pages depending on which icon is tapped. I'm aware that the code below doesn't execute, i'm just trying to show what i've tried.

My code:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  _onTap(int index) {
    Navigator.of(context)
        .push(MaterialPageRoute<Null>(builder: (BuildContext context) {
      return _children[_currentIndex];
    }));}

  final List<Widget> _children = [
    HomePage(),
    InboxPage(),
    SignInPage()
  ];

  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
      SizeConfig().init(context);
      return Scaffold(
        appBar: PreferredSize(preferredSize: Size(double.infinity, 75),
          child: AppBar(
              elevation: 0.0,
              centerTitle: false,
              title: Column(
                children: <Widget>[
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Text(
                      currentDate,
                      textAlign: TextAlign.left,
                      style: TextStyle(
                          color: titleTextColor,
                          fontWeight: subTitleFontWeight,
                          fontFamily: titleFontFamily,
                          fontSize: subTitleFontSize),
                    ),
                  ),
                  SizedBox(
                    height: 15,
                  ),
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Text(
                      'Some text here',
                      style: TextStyle(
                          color: titleTextColor,
                          fontWeight: titleTextFontWeight,
                          fontFamily: titleFontFamily,
                          fontSize: titleFontSize),
                    ),
                  ),
                ],
              ),
              backgroundColor: kPrimaryColor,
              shape: titleBarRounding
          ),
        ),
        body: BodyOne(),
        bottomNavigationBar: BottomNavigationBar(
            currentIndex: _currentIndex,
            type: BottomNavigationBarType.fixed,
            items: [
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                title: Text('Home'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.mail),
                title: Text('Inbox'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.account_circle),
                title: Text('Account'),


              )
            ],
          onTap: () => _onTap(_currentIndex),
        ),);
    }
  }

Thanks in advance.

Answer

Didier Peran Ganthier picture Didier Peran Ganthier · Aug 6, 2020

The screen you are in can't be part of the Screens you're navigating to and you don't need to push a new screen each time you just have to change selectedPage, this is an example of how it should look:

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int selectedPage = 0;

  final _pageOptions = [
    HomeScreen(),
    InboxScreen(),
    SignInScreen()
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.white,
        body: _pageOptions[selectedPage],
        bottomNavigationBar: BottomNavigationBar(
          items: [
            BottomNavigationBarItem(icon: Icon(Icons.home, size: 30), title: Text('Home')),
            BottomNavigationBarItem(icon: Icon(Icons.mail, size: 30), title: Text('Inbox')),
            BottomNavigationBarItem(icon: Icon(Icons.account_circle, size: 30), title: Text('Account')),
          ],
          selectedItemColor: Colors.green,
          elevation: 5.0,
          unselectedItemColor: Colors.green[900],
          currentIndex: selectedPage,
          backgroundColor: Colors.white,
          onTap: (index){
            setState(() {
              selectedPage = index;
            });
          },
        )
    );
  }
}

Let me know if you need more explanation.