64

How to change background color of TabBar without changing the AppBar? The TabBar does not have a background property, is there a workaround?

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
amater
  • 661
  • 1
  • 6
  • 10

9 Answers9

70

You can change the color of the TabBar by changing the Theme primaryColor like that:

return MaterialApp(
      theme: ThemeData(
        brightness: Brightness.light,
      // add tabBarTheme 
      tabBarTheme: const TabBarTheme(
        labelColor: Colors.pink[800],
        labelStyle: TextStyle(color: Colors.pink[800]), // color for text
        indicator: UnderlineTabIndicator( // color for indicator (underline)
          borderSide: BorderSide(color: ConstColor.primary))),
        primaryColor: Colors.pink[800], // outdated and has no effect to Tabbar
        accentColor: Colors.cyan[600] // deprecated,
      ),
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              indicatorColor: Colors.lime,
              tabs: [
                Tab(icon: Icon(Icons.directions_car)),
                Tab(icon: Icon(Icons.directions_transit)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
            title: Text('Tabs Demo'),
          ),
          body: TabBarView(
            children: [
              Icon(Icons.directions_car),
              Icon(Icons.directions_transit),
              Icon(Icons.directions_bike),
            ],
          ),
        ),
      ),
    );

If you are not using it in an AppBar you could wrap the TabBar in a Material widget and set the color attribute, like that:

class TabBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Tabs Demo'),
        ),
        body: DefaultTabController(
          length: 3,
          child: Column(
            children: <Widget>[
              Container(
                constraints: BoxConstraints(maxHeight: 150.0),
                child: Material(
                  color: Colors.indigo,
                  child: TabBar(
                    tabs: [
                      Tab(icon: Icon(Icons.directions_car)),
                      Tab(icon: Icon(Icons.directions_transit)),
                      Tab(icon: Icon(Icons.directions_bike)),
                    ],
                  ),
                ),
              ),
              Expanded(
                child: TabBarView(
                  children: [
                    Icon(Icons.directions_car),
                    Icon(Icons.directions_transit),
                    Icon(Icons.directions_bike),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Kirill
  • 108
  • 4
Antonino
  • 3,775
  • 1
  • 19
  • 16
  • 16
    It changed the whole AppBar not onlye TabBar, I need to change only the TabBar – amater May 28 '18 at 13:32
  • As @amater mentioned, this will not only change the `TabBar` color but also the `AppBar` color. This was explicitly mentioned in the question to `...change background color of TabBar without changing the AppBar...`. [This should be the accepted answer](https://stackoverflow.com/a/65779947/9111447) – MJ12358 May 02 '22 at 20:18
  • this is what you're looking for : `Material( color: Colors.indigo, child: TabBar(...),)` – shaderone May 24 '22 at 12:00
  • 1
    TabBarTheme doesn't have primaryColor – Christian Findlay Oct 25 '22 at 04:14
63

Create a simple Widget for this, cannot be simpler:

class ColoredTabBar extends Container implements PreferredSizeWidget {
  ColoredTabBar(this.color, this.tabBar);

  final Color color;
  final TabBar tabBar;

  @override
  Size get preferredSize => tabBar.preferredSize;

  @override
  Widget build(BuildContext context) => Container(
    color: color,
    child: tabBar,
  );
}
Noor Dawod
  • 739
  • 5
  • 6
  • This worked for changing the color of the tab bar. I was hoping to find something where the tab bar has an elevation of 0 and is transparent. – Eric Duffett Feb 17 '19 at 13:29
  • The ripple effects when user clicks on Tabs are not working anymore with this solution, anybody knows why? – 最白目 May 29 '19 at 14:07
  • 6
    @最白目Please wrap the `tabBar` field above in a `Material` widget and set type to `MaterialType.transparency` – hysabone.com Aug 08 '19 at 17:48
58

Screenshot:

enter image description here


Code:

TabBar get _tabBar => TabBar(
  tabs: [
    Tab(icon: Icon(Icons.call)),
    Tab(icon: Icon(Icons.message)),
  ],
);
  
@override
Widget build(BuildContext context) {
  return DefaultTabController(
    length: 2,
    child: Scaffold(
      appBar: AppBar(
        title: Text('AppBar'),
        bottom: PreferredSize(
          preferredSize: _tabBar.preferredSize,
          child: ColoredBox(
            color: Colors.red,
            child: _tabBar,
          ),
        ),
      ),
    ),
  );
}
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
17

Change Background Color of TabBar in Flutter..

Simply use TabBar in Body of Scaffold, wrap it with Column Widget so that, you can use both without any issue. Wrap TabBar with Container widget to change the tab color. In this way you can change the color of Tab bar in FLutter.

Here's the sample Code...

   Scaffold(
       appBar: AppBar(
       backgroundColor: const Color(0xFF3baee7),
       title: Text("Jobs"),
        ),
      body: Column(      // Column
         children: <Widget>[
          Container(
            color: Colors.deepOrangeAccent,        // Tab Bar color change
             child: TabBar(           // TabBar
             controller: tabController,
             unselectedLabelColor: Colors.lightBlue[100],
             labelColor: const Color(0xFF3baee7),
             indicatorWeight: 2,
             indicatorColor: Colors.blue[100],
             tabs: <Widget>[               
               Tab(
                 text: "All Jobs",
               ),
               Tab(
                 text: "Most Recent",
               ),
               Tab(
                 text: "Saved Jobs",
               )
             ],
           ),
         ),
         Expanded(
             flex: 3,
             child: TabBarView(         // Tab Bar View
             physics: BouncingScrollPhysics(),
             controller: tabController,
             children: <Widget>[AllJobScreen(), AllJobScreen(), AllJobScreen()],
               ),
            ),
         ],
    ),
  );
Sumit Singh
  • 1,150
  • 13
  • 17
  • 1
    I used the above method, wrapped the Tabbar in a container to have the unselected tabbar as grey and set the tabbar indicator color, so it shows as selected color. – Ant D Aug 19 '19 at 13:30
5

Simple and concise.

class ColoredTabBar extends ColoredBox implements PreferredSizeWidget {
  ColoredTabBar({this.color, this.tabBar}) : super(color: color, child: tabBar);

  final Color color;
  final TabBar tabBar;

  @override
  Size get preferredSize => tabBar.preferredSize;
}
2

You can change the Tabbar background-color, when Tabbar is inside the Material widget.

           Material(
              color: Colors.white, //Tabbar background-color
              child: TabBar(
                isScrollable: true,
                labelStyle: Theme.of(context).tabBarTheme.labelStyle,
                unselectedLabelStyle:
                    Theme.of(context).tabBarTheme.unselectedLabelStyle,
                labelColor: Theme.of(context).tabBarTheme.labelColor,
                unselectedLabelColor:
                    Theme.of(context).tabBarTheme.unselectedLabelColor,
                indicatorColor: Theme.of(context).primaryColor,
                tabs: [
                  Tab(text: 'tab 1'),
                  Tab(text: 'tab 2'),
                  Tab(text: 'tab 3'),
                  Tab(text: 'tab 4'),
                ],
              ),
            ),
Isuru Jayathissa
  • 478
  • 4
  • 15
2

with a little trick

bottom: TabBar(
 labelPadding: EdgeInsets.zero, // this one make 0
 tabs: [
     for (final t in [1, 2, 3])
     Container(
     width: double.infinity,
     color: Colors.blue, // color same as background
     child: Tab(
     text: "tab $t",
      ),
     )
  ],
),

so the trick is, wrap the tab with a container and make the width of the container the same and then change the color of the container according to your wishes

malik kurosaki
  • 1,747
  • 15
  • 9
1

So if you are looking for to change the specific tab color and then you can try the following code:

  1. Create a variable of color:
    Color tabColor=Colors.green;

  2. Create onTap method inside the TabBar and inside the tab bar create setState() method code is given below:

    onTap: (index) {
       setState(() {
    
         if(index==0) { tabColor = Colors.lightGreen;}
         if(index==1) {tabColor = Colors.yellow;}
         if(index==2) {tabColor = Colors.green;}
         if(index==3) {tabColor = Colors.red;}
         if(index==4) {tabColor = Colors.deepPurple;}                      
       });
       print(index);
     },
    
  3. Create an indicator and give some radius as per your requirement and change the color code is given:

    indicator: BoxDecoration(
       borderRadius: BorderRadius.only(topLeft: 
      Radius.circular(10),topRight: Radius.circular(10)),
       color: tabColor
    ),
    
Sven Eberth
  • 3,057
  • 12
  • 24
  • 29
0

for use with SliverPersistenHeader (e.t.c collapsing with sliver appbar in nested scrollview)

 class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
   _SliverAppBarDelegate(this._tabBar);

  final TabBar _tabBar;

  @override
  double get minExtent => _tabBar.preferredSize.height;
  @override
  double get maxExtent => _tabBar.preferredSize.height;

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return new Container(
      child: _tabBar,
      color: Colors.red,
    );
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return false;
  }
}
Hamdam Muqimov
  • 319
  • 2
  • 7