2

In my app I have two pages Page1 and Page2. I also have tab bar which is displayed at the bottom of the screen. The problem is that the TabBar goes away when I use Navigator.push from one of the pages. Check out the animations below:

enter image description here

Here is all my code:

void main() => runApp(App());

class App extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      title: "Hello",
      home: DefaultTabController(
        length: 2,
        child: Scaffold(
          bottomNavigationBar: TabBar(tabs: <Widget>[
              Tab(icon: Icon(Icons.directions_car)),
              Tab(icon: Icon(Icons.do_not_disturb))
            ],
            labelColor: Colors.black

            )
          ,
          body: TabBarView(children: <Widget>[
              Page1(), 
              Page2()
          ])
        )

      )
    );

  }
}

class Page1 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text('Page 1'),
      ),
      body: FlatButton(
        child: Text('Go to Page 2'), 
        onPressed: () {
          Navigator.push(context, MaterialPageRoute(
            builder: (context) {
              return Page2(); 
            }
          ));
        },
        color: Colors.orange
      )
    );

  }

}

class Page2 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text('Page 2'),
      ),
      body: FlatButton(
        child: Text('Go to Page 1'), 
        onPressed: () {
          Navigator.push(context, MaterialPageRoute(
            builder: (context) {
              return Page1(); 
            }
          ));
        },
        color: Colors.purple
      )
    );

  }

}
john doe
  • 9,220
  • 23
  • 91
  • 167

3 Answers3

2

what you want can be easily done with the help of cupertino widgets.

Example Code:

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

void main() => runApp(MainPage());

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      debugShowCheckedModeBanner: false,
      title: 'Demo App',
      home: CupertinoTabScaffold(
        tabBar: CupertinoTabBar(
          items: [
            BottomNavigationBarItem(
                icon: Icon(Icons.event), title: Text("Tab 1")),
            BottomNavigationBarItem(
                icon: Icon(Icons.group), title: Text("Tab 2")),
          ],
          currentIndex: _currentIndex,
          onTap: (int) {
            setState(() {
              _currentIndex = int;
            });
          },
        ),
        tabBuilder: (context, int) {
          switch (int) {
            case 0:
              {
                return CupertinoTabView(
                  builder: (context) {
                    return Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text('Tab 1 Content'),
                          ),
                          CupertinoButton.filled(
                              child: Text('Goto next Page in Tab1'),
                              onPressed: () {
                                Navigator.push(context,
                                    CupertinoPageRoute(builder: (context) {
                                  return Body(int);
                                }));
                              })
                        ],
                      ),
                    );
                  },
                );
              }
              break;
            case 1:
              {
                return CupertinoTabView(
                  builder: (context) {
                    return Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text('Tab 2 Content'),
                          ),
                          CupertinoButton.filled(
                              child: Text('Goto next Page in Tab2'),
                              onPressed: () {
                                Navigator.push(context,
                                    CupertinoPageRoute(builder: (context) {
                                  return Body(int);
                                }));
                              })
                        ],
                      ),
                    );
                  },
                );
              }
              break;
          }
        },
      ),
    );
  }
}

class Body extends StatefulWidget {
  final int index;

  Body(this.index);

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

class _BodyState extends State<Body> {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
        navigationBar: CupertinoNavigationBar(
          middle: Text('Page2 of Tab${widget.index}'),
        ),
        child: Center(
          child: Container(
            child: Text('Page 2'),
          ),
        ));
  }
}
anmol.majhail
  • 48,256
  • 14
  • 136
  • 105
1

EDIT

Sorry I misunderstood the question, this may be a duplicate of Flutter: Keep BottomNavigationBar When Push to New Screen with Navigator

Original answer

Use a single master page and replace the body dynamically with each sub page (containing their own content) :

Example :

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _HomePageState extends State<HomePage> {
  // current page index of the bottom navigation bar
  int _currentIndex = 0;

  // update the state of the index on tab tap
  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    // list of pages of the bottom navigation bar
    final List<Widget> _children = [
      FirstPage(title: "My page 1"),
      SecondPage(title: "My page 2"),
      ThirdPage(title: "My page 3"),
    ];

    return Scaffold(
      backgroundColor: Colors.transparent,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: _children[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        onTap: onTabTapped,
        currentIndex: _currentIndex,
        type: BottomNavigationBarType.shifting,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.event), title: Text("Page 1")),
          BottomNavigationBarItem(icon: Icon(Icons.group), title: Text("Page 2")),
          BottomNavigationBarItem(icon: Icon(Icons.camera_alt), title: Text("Page 3")),
        ],
      ),
    );
  }
}

Then FirstPage, SecondPage, ThirdPage can content only their own content :

import 'package:flutter/material.dart';

class FirstPage extends StatefulWidget {
  FirstPage({Key key, this.title}) : super(key: key);

  final String title;

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

class _FirstPageState extends State<FirstPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: // your body content
    );
  }
}
Yann39
  • 14,285
  • 11
  • 56
  • 84
  • Thanks! But how does it solve the problem of clicking on a button and then using Navigator.push to load another page. Do you have complete code for your example? The example I build is using a button press to Navigate to Page 2 which does not show the TabBar. – john doe May 23 '19 at 15:02
  • The Tabs in my app are working fine. The problem happens if I click on a button and Navigator to Page 2 then the tabs don't appear. – john doe May 23 '19 at 15:04
  • 1
    Sorry John, I misunderstood your question. So this may be a duplicate of https://stackoverflow.com/questions/49628510/flutter-keep-bottomnavigationbar-when-push-to-new-screen-with-navigator – Yann39 May 23 '19 at 17:14
0

Pushing a route will set the Widget as the child of the MaterialApp. Every screen should contain it's own scaffold with it's own BottonNavigatorBar.

ZeRj
  • 1,612
  • 14
  • 24
  • Create a new Widget in a seperate file for your BottomNavigationBar which you can then use on every page. – ZeRj May 23 '19 at 17:22