How to add Tabbar in SliverAppBar on Flutter?

Can we add TabBar in our SliverAppBar ? Since SliverAppBar has bottom property so I thought we can add Tabbar in our SliverAppBar, but the problem is TabBar needs DefaultTabbarController and DefaultTabbarController only works in Material Widget and SliverAppbar only work in Scaffold Body not in my appbar , but I need my scaffold body to have TabView, Can somebody Clear this up, I'm so confused ?

2 answers

  • answered 2018-07-11 05:10 Dhiraj Sharma

    You can wrap SilverAppBar(which has TabBar as bottom) & SilverFillRemaining(wraps TabBarView) with CustomScrollView. Then set set CustomScrollView as body of Scaffold. For this you need to create a TabController.

    Full Example here .

    import 'package:flutter/material.dart';
    
    class SilverAppBarWithTabBarScreen extends StatefulWidget {
      @override
      _SilverAppBarWithTabBarState createState() => _SilverAppBarWithTabBarState();
    }
    
    class _SilverAppBarWithTabBarState extends State<SilverAppBarWithTabBarScreen>
        with SingleTickerProviderStateMixin {
      TabController controller;
    
      @override
      void initState() {
        super.initState();
        controller = new TabController(length: 3, vsync: this);
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new CustomScrollView(
            slivers: <Widget>[
              new SliverAppBar(
                title: Text("Silver AppBar With ToolBar"),
                pinned: true,
                expandedHeight: 160.0,
                bottom: new TabBar(
                  tabs: [
                    new Tab(text: 'Tab 1'),
                    new Tab(text: 'Tab 2'),
                    new Tab(text: 'Tab 3'),
                  ],
                  controller: controller,
                ),
              ),
              new SliverFillRemaining(
                child: TabBarView(
                  controller: controller,
                  children: <Widget>[
                    Text("Tab 1"),
                    Text("Tab 2"),
                    Text("Tab 3"),
                  ],
                ),
              ),
            ],
          ),
        );
      }
    }
    

  • answered 2018-07-11 08:50 ap14

    I was able to achieve what you was asking. But I have only problem i.e. When i add a Scrolling widget in TabView it doesn't produce the required result. I have open an issue on github. Here is my code.

    class HomePage extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => HomePageState();
    }
    
    class HomePageState extends State<HomePage>
        with SingleTickerProviderStateMixin {
      TabController tabController;
      @override
      void initState() {
        super.initState();
        tabController = TabController(length: 2, vsync: this);
      }
    
      @override
      Widget build(BuildContext context) {
        Color tabColor = Theme.of(context).primaryColorDark;
        TextStyle tabStyle = TextStyle(color: tabColor);
        return SafeArea(
          child: Scaffold(
            body: CustomScrollView(
              slivers: <Widget>[
                SliverAppBar(
                  title: Text("AppBar"),
                  floating: true,
                  primary: true,
                  pinned: false,
                ),
                SliverFillRemaining(
                  child: Scaffold(
                    appBar: TabBar(
                    controller: tabController,
                    tabs: <Widget>[
                      Tab(
                        child: Text(
                          'Tab1',
                         style: tabStyle,
                        ),
                      ),
                      Tab(
                        child: Text(
                          'Tab2',
                        style: tabStyle,
                        ),
                      ),
                    ],
                  ),
                    body: TabBarView(
                      controller: tabController,
                      children: <Widget>[
                        Scaffold(
                          body: Text('Tab One'),
                        ),
                        Scaffold(
                          body: Text('Tab Two'),
                        ),                  
                      ],
                    ),
                  ),
                  ),
              ],
            ),
          ),
        );
      }
    }
    

    Emulator Screen