24

I'm using a TabBar widget and I'd like to customize the height and width of the indicator. I can't see any other property besides color I can modify.

enter image description here

Albert Lardizabal
  • 6,548
  • 7
  • 34
  • 34

11 Answers11

48

You can use indicatorSize: TabBarIndicatorSize.label on the TabBar to make the indicator the same size as the label.

Or you could set the indicator directly, this is a Decoration which you can customize:

AppBar(
    bottom: TabBar(
        indicator: UnderlineTabIndicator(
          borderSide: BorderSide(width: 5.0),
          insets: EdgeInsets.symmetric(horizontal:16.0)
        ),
        tabs: [
          Tab(text: 'tab 1'),
          Tab(text: 'tab 2'),
          Tab(text: 'tab 3'),
        ],
     ),
);

For more customisation options check this post

Jochem Toolenaar
  • 899
  • 10
  • 9
46

Give your TabBar a property of isScrollable: true if you don't want the tabs to expand to fill the screen horizontally the way they do by default.

You can use a Container wrapped in a PreferredSize to size the TabBar. (The PreferredSize is only necessary if you want it to live in the bottom slot of an AppBar.) This has the effect of making the indicators appear narrower because the TabBar doesn't fill the screen. However, the indicator has a hard coded height. If you don't like it, you'll have to import your own copy of tabs.dart and customize the constants in that file.

Note that you can also use a Container to set the height of the individual Tabs, although that doesn't seem like what you're trying to do.

screenshot

import 'package:flutter/material.dart';


void main() {
  runApp(new MaterialApp(
    home: new MyApp(),
  ));
}



class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: 2,
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text('Tabs Demo'),
          bottom: new PreferredSize(
            preferredSize: new Size(200.0, 200.0),
            child: new Container(
              width: 200.0,
              child: new TabBar(
                tabs: [
                  new Container(
                    height: 200.0,
                    child: new Tab(text: 'hello'),
                  ),
                  new Container(
                    height: 200.0,
                    child: new Tab(text: 'world'),
                  ),
                ],
              ),
            ),
          ),
        ),
        // body: ...
      ),
    );
  }

}
Collin Jackson
  • 110,240
  • 31
  • 221
  • 152
8

In the same way as this answer https://stackoverflow.com/a/44273493/5938089, The best is to use containers, but I will only use one.

For a change, I will use a bottom bar

bottomNavigationBar: new Material(
    color: Colors.teal,
    child: new Container(
      height: 60.0,
      child: new TabBar(
        controller: controller,
        tabs: <Widget>[
            new Tab(icon: new Icon(Icons.access_alarm)),
            new Tab(icon: new Icon(Icons.account_balance)),
        ]
      ),
    )
  ),

Screen Shot

Erick Dávila
  • 347
  • 5
  • 9
4

You can adjust the spacing between the tabs -> labelPadding: EdgeInsets.symmetric (horizontal: 5),

Hasan_H
  • 77
  • 4
2

You can use property TabBar(indicatorWeight:detail Height).

double-beep
  • 5,031
  • 17
  • 33
  • 41
Cavalier123
  • 191
  • 1
  • 5
0

Check out Tab Indicator Styler package for more advanced styling.

K.Amanov
  • 1,278
  • 14
  • 23
0
appBar: new AppBar(
        title: Text("TabBar demo"),
        bottom: PreferredSize(
          preferredSize: Size.fromHeight(kToolbarHeight),
          child: Align(
            alignment: Alignment.centerLeft,
            child: new TabBar(
              controller: _tabController,
              indicator: UnderlineTabIndicator(
                borderSide: BorderSide(width: 3.0, color: Colors.red),
                insets: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10),
              ),
              indicatorSize: TabBarIndicatorSize.label,
              isScrollable: true,
              onTap: (index) {
                print(index);
                _currentIndex = index;
                setState(() {});
              },
              tabs: [
                new Container(
                  height: 50.0,
                  width: 80,
                  // color: Colors.red,
                  child: new Tab(text: '1'),
                ),
                new Container(
                  height: 50.0,
                  width: 80,
                  // color: Colors.red,
                  child: new Tab(text: '222'),
                ),
                new Container(
                  height: 50.0,
                  width: 80,
                  // color: Colors.red,
                  child: new Tab(text: '333333'),
                ),
              ],
            ),
          ),
        ),
      ),
      // body: ...
    );
  • give tabs item fixed width,and set indicatorSize: TabBarIndicatorSize.label, – ilovesshan Oct 14 '21 at 10:03
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Muhammedogz Oct 14 '21 at 11:18
0

Try to do this in the TabBar

                  indicatorWeight: 0,
                  indicator: UnderlineTabIndicator(
                    borderSide: BorderSide(
                      width: 0.1,
                      color: AppColor.themeColor,
                    ),
Dionke
  • 11
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 15 '21 at 10:38
0

You can design the underline indicator with border-radius, and the length of the indicator according to the text container length.

child: TabBar(
    indicatoenter code herer: BoxDecoration(
        borderRadius: BorderRadius.circular(10),
        color: widgetBlueColor,
    ),
    indicatorPadding: const EdgeInsets.only(top: 33, bottom: 2),
    labelColor: widgetBlueColor,
    unselectedLabelColor: Colors.black87,
    labelPadding: const EdgeInsets.only(bottom: 16),
    indicatorSize: TabBarIndicatorSize.label,
    labelStyle: const TextStyle(fontWeight: FontWeight.w500),
    tabs: const [
        Tab(
            child: SizedBox(
                width: 60,
                child: Text(
                    "DETAILS",
                    textAlign: TextAlign.center,
                ),
            ),
        ),
        Tab(
            child: SizedBox(
                width: 85,
                child: Text(
                    "DOCUMENTS",
                    textAlign: TextAlign.center,
                ),
            )
        )
    ]
)
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
0

if you decrease default tab bar size use SizeBox().

                             SizedBox(
                                  height: 40,
                                  child: TabBar(
                                      isScrollable: true,
                                      indicatorSize: TabBarIndicatorSize.tab,
                                      labelColor: Colors.black,
                                      unselectedLabelColor: Colors.grey,
                                      labelStyle: TextStyle(
                                          fontSize: 15,
                                          fontWeight: FontWeight.w500),
                                      unselectedLabelStyle: TextStyle(
                                          fontSize: 14,
                                          fontWeight: FontWeight.w400),

                                      padding:
                                          EdgeInsets.symmetric(horizontal: 12),
                                      indicator: BoxDecoration(
                                          borderRadius: BorderRadius.circular(16),
                                          color: AppTheme().orange),
                                      tabs: getTab(),
                                      controller: _tabController),
                                ),
adarsh
  • 403
  • 3
  • 8
0

For creating WhatsApp like tabbar you can isScrollable: true for TabBar then get the width of the screen and calculate the width for 3 tabs other than camera(now community), then wrap your 3 Tab widget inside SizedBox with calculated width. Here's the code

//get screen size
static Size screen =
      MediaQueryData.fromWindow(WidgetsBinding.instance.window).size;

// Calculate common width for 3 tabs
final double screenWidth = Data.screen.width;
final tabWidth = screenWidth / 4.8; // works for 6.5inch display

List<Widget> myTabs = [
      const HomePageTab(
        icon: Icons.groups_rounded,
      ),
      SizedBox(
        width: tabWidth,
        child: const HomePageTab(
          title: 'Chats',
        ),
      ),
      SizedBox(
        width: tabWidth,
        child: const HomePageTab(
          title: 'Status',
        ),
      ),
      SizedBox(
        width: tabWidth,
        child: const HomePageTab(
          title: 'Calls',
        ),
      ),
    ];
kartik
  • 93
  • 9