Flutter bottom navigation where one page has tabs

4,157

Solution 1

You can use nested Scaffold widgets. This works in Flutter 1.1.8:

// This is the outer Scaffold. No AppBar here
Scaffold(
  // Workaround for https://github.com/flutter/flutter/issues/7036
  resizeToAvoidBottomPadding: false, 
  body: _getCurrentPage(),  // AppBar comes from the Scaffold of the current page 
  bottomNavigationBar: BottomNavigationBar(
    // ...
  )
)

Solution 2

As far as I know you can't , but I managed to solve this problem by adding a separate AppBar to each page navigated through the bottomNavigationBar:

provide each of your _pages with a separate app bar, and remove the main one from your build method.

Share:
4,157
user1321706
Author by

user1321706

Updated on December 09, 2022

Comments

  • user1321706
    user1321706 over 1 year

    I would like to create A scaffold with bottom navigation bar, and an app bar which always displays current page title. When I change bottom bar option, the content changes obviously. Everything this far is ok with classic NavigationBar structure. But the problem starts when on of the content pages should have tabs on top of them. I have my appbar created in parents Scaffold. Is there anyway to add tabs to parent widgets appBar ?

    My AppBar + BottomNavBar page:

    class MainPage extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _MainPageState();
      }
    }
    class _MainPageState extends State<MainPage> {
    
      int _currentPageIndex;
      List<Widget> _pages = List();
    
      Widget _getCurrentPage() => _pages[_currentPageIndex];
    
      @override
      void initState() {
        setState(() {
          _currentPageIndex = 0;
    
          _pages.add(BlocProvider(bloc: AgendaBloc(), child: AgendaPage()));
          _pages.add(SpeakersPage());
          _pages.add(MenuPage());
        });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: MyAppBar( title: 'Agenda'),
          body: _getCurrentPage(),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _currentPageIndex,
            onTap: (index){
              setState(() {
                _currentPageIndex = index;
              });
            },
            items: [
              BottomNavigationBarItem(
                icon: Icon(Icons.content_paste),
                title: Text('Agenda'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.group),
                title: Text('Speakers'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.menu),
                title: Text('Menu'),
              ),
            ],
          ),
        );
      }
    }
    

    Now lets say that I want my AgendaPage widget to display tabs on top of view. Is there any easy, non-hacky way to do this ?

    Desired effect: Tabs page

    No Tabs page

  • user1321706
    user1321706 over 5 years
    Thats what I managed to do. Transition from "app-bar-only-page" to another is smooth. However there is an 'ugly' redraw when switching to page with tabs (app bar blinks for a sec). Thought there might be something I can do about it, just dont know yet.
  • Mazin Ibrahim
    Mazin Ibrahim over 5 years
    if you want the app bar to shrink take a look at sliverAppbar
  • user1321706
    user1321706 over 5 years
    Marking this answer as correct, since this is what I've ended up doing. Seems to be working well. Just incase someone made my mistake: If you build tabs page with StreamBuilder, note that it will always emit null as the first element. This may cause flutter to render your "No data view" (empty Container probably), and then the correct one. The effect is that tabs 'blinks' every time you switch to them.