tabbed_view 1.0.0
tabbed_view: ^1.0.0 copied to clipboard

Flutter widget inspired by the classic Desktop-style tab component. Supports customizable themes.

pub

Flutter widget inspired by the classic Desktop-style tab component. Supports customizable themes.

classiccut darkcut mobilecut minimalistcut fromthescratchcut

The TabbedView renders the presentation of the model.

The TabbedViewModel stores the tab data as name, content, buttons or any dynamic value.

Get started #

The TabbedViewTheme.classic() method builds the default theme.

    List<TabData> tabs = [];
    for (var i = 1; i < 7; i++) {
      Widget tabContent = Center(child: Text('Content $i'));
      tabs.add(TabData(text: 'Tab $i', content: tabContent));
    }
    TabbedWiew tabbedView = TabbedWiew(controller: TabbedWiewController(tabs));

classic

Content builder #

It allows creating the contents of the tab dynamically during the selection event.

    var tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
      TabData(text: 'Tab 3')
    ];

    TabbedWiew tabbedView = TabbedWiew(
        controller: TabbedWiewController(tabs),
        contentBuilder: (BuildContext context, int tabIndex) {
          int i = tabIndex + 1;
          return Center(child: Text('Content $i'));
        });

Close button tooltip #

    var tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
      TabData(text: 'Tab 3')
    ];
    TabbedWiew tabbedView = TabbedWiew(
        controller: TabbedWiewController(tabs),
        closeButtonTooltip: 'Click here to close the tab');

Tab #

Adding buttons #

    TabData tab = TabData(text: 'Tab', buttons: [
      TabButton(icon: Icons.star, onPressed: () => print('Hello!'))
    ]);
    TabbedWiew tabbedView = TabbedWiew(controller: TabbedWiewController([tab]));

tabbutton

Overriding theme color

    var tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2', buttons: [
        TabButton(
            icon: Icons.star,
            color: Colors.green,
            onPressed: () => print('Hello!'))
      ])
    ];
    TabbedWiew tabbedView = TabbedWiew(controller: TabbedWiewController(tabs));

tabbuttoncolor

Removing the close button #

    var tabs = [
      TabData(text: 'Tab'),
      TabData(text: 'Non-closable tab', closable: false)
    ];
    TabbedWiew tabbedView = TabbedWiew(controller: TabbedWiewController(tabs));

nonclosabletab

Close listener #

    bool _onTabClosing(int tabIndex) {
      if (tabIndex == 0) {
        print('The tab $tabIndex is busy and cannot be closed.');
        return false;
      }
      print('Closing tab $tabIndex...');
      return true;
    }

    List<TabData> tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
      TabData(text: 'Tab 3')
    ];
    TabbedWiew tabbedView = TabbedWiew(
        controller: TabbedWiewController(tabs), onTabClosing: _onTabClosing);

Selection listener #

    _onTabSelection(int? newTabIndex) {
      print('The new selected tab is $newTabIndex.');
    }

    List<TabData> tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
      TabData(text: 'Tab 3')
    ];
    TabbedWiew tabbedView = TabbedWiew(
        controller: TabbedWiewController(tabs),
        onTabSelection: _onTabSelection);

Tabs area #

Buttons #

    TabbedWiewController controller = TabbedWiewController([]);

    TabbedWiew tabbedView = TabbedWiew(
        controller: controller,
        tabsAreaButtonsBuilder: (context, tabsCount) {
          List<TabButton> buttons = [];
          buttons.add(TabButton(
              icon: Icons.add,
              onPressed: () {
                int millisecond = DateTime.now().millisecondsSinceEpoch;
                controller.addTab(TabData(text: '$millisecond'));
              }));
          if (tabsCount > 0) {
            buttons.add(TabButton(
                icon: Icons.delete,
                onPressed: () {
                  if (controller.selectedIndex != null) {
                    controller.removeTab(controller.selectedIndex!);
                  }
                }));
          }
          return buttons;
        });

tabsareabuttons

Themes #

Tab #

Text style

    var tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
    ];

    TabbedViewTheme theme = TabbedViewTheme.classic();
    theme.tabsArea.tab.textStyle = TextStyle(fontSize: 20, color: Colors.blue);

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

tabtextstyle

Alignment

    var tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
    ];

    TabbedViewTheme theme = TabbedViewTheme.classic();
    theme.tabsArea.tab
      ..textStyle = TextStyle(fontSize: 20)
      ..verticalAlignment = VerticalAlignment.top;

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

topalignment

Tabs area #

Color

  • The default TabsAreaTheme color is null.
    var tabs = [TabData(text: 'Tab 1'), TabData(text: 'Tab 2')];

    TabbedViewTheme theme = TabbedViewTheme.minimalist();
    theme.tabsArea.color = Colors.green[100];

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

tabsareacolor

Tab gaps

  • Gap before the tabs (allows negative value).
  • Gap between tabs (allows negative value).
  • Minimum gap after tabs. Separates the last tab and the buttons area.
    List<TabData> tabs = [];
    for (var i = 1; i < 7; i++) {
      tabs.add(
          TabData(text: 'Tab $i', content: Center(child: Text('Content $i'))));
    }

    TabbedViewTheme theme = TabbedViewTheme.classic();
    theme.tabsArea
      ..initialGap = 20
      ..middleGap = 5
      ..minimalFinalGap = 5;

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

customgap

Buttons area

Button icon for the hidden tabs menu
    List<TabData> tabs = [];
    for (var i = 1; i < 7; i++) {
      tabs.add(TabData(text: 'Tab $i'));
    }

    TabbedViewTheme theme = TabbedViewTheme.classic();
    theme.tabsArea.buttonsArea.hiddenTabsMenuButtonIcon =
        Icons.arrow_drop_down_circle_outlined;

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

hiddentabsbuttonicon

Max width

    List<TabData> tabs = [];
    for (int i = 1; i < 11; i++) {
      tabs.add(TabData(text: 'Tab $i'));
    }

    TabbedViewTheme theme = TabbedViewTheme.classic()..menu.maxWidth = 100;

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

menumaxwidth

Ellipsis on overflow text

    var tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
      TabData(text: 'Tab 3'),
      TabData(
          text: 'The name of the tab is so long that it doesn'
              't fit on the menu')
    ];

    TabbedViewTheme theme = TabbedViewTheme.classic()
      ..menu.ellipsisOverflowText = true;

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

menuellipsis

Predefined themes #

Classic theme

    List<TabData> tabs = [];
    for (var i = 1; i < 7; i++) {
      tabs.add(TabData(text: 'Tab $i', content:  Center(child: Text('Content $i'))));
    }
    TabbedWiewController controller = TabbedWiewController(tabs);

    TabbedWiew tabbedView = TabbedWiew(
        controller: controller,
        theme: TabbedViewTheme.classic());

classic2

Color set
    List<TabData> tabs = [];
    for (var i = 1; i < 7; i++) {
      tabs.add(TabData(text: 'Tab $i', content:  Center(child: Text('Content $i'))));
    }
    TabbedWiewController controller = TabbedWiewController(tabs);

    TabbedViewTheme theme = TabbedViewTheme.classic(colorSet: Colors.green);

    TabbedWiew tabbedView = TabbedWiew(
        controller: controller,
        theme: theme);

classiccolorset

Dark theme

    List<TabData> tabs = [];
    for (var i = 1; i < 7; i++) {
      tabs.add(TabData(text: 'Tab $i'));
    }
    TabbedWiewController controller = TabbedWiewController(tabs);

    var contentBuilder = (BuildContext context, int index) {
      int i = index + 1;
      Text text = Text('Content $i', style: TextStyle(color: Colors.white));
      return Center(child: text);
    };

    TabbedWiew tabbedView = TabbedWiew(
        controller: controller,
        contentBuilder: contentBuilder,
        theme: TabbedViewTheme.dark());

    Container container = Container(child: tabbedView, color: Colors.black);

dark

Color set
    List<TabData> tabs = [];
    for (var i = 1; i < 7; i++) {
      tabs.add(TabData(text: 'Tab $i'));
    }
    TabbedWiewController controller = TabbedWiewController(tabs);

    var contentBuilder = (BuildContext context, int index) {
      int i = index + 1;
      Text text = Text('Content $i', style: TextStyle(color: Colors.white));
      return Center(child: text);
    };

    TabbedViewTheme theme = TabbedViewTheme.dark(colorSet: Colors.indigo);

    TabbedWiew tabbedView = TabbedWiew(
        controller: controller, contentBuilder: contentBuilder, theme: theme);

    Container container = Container(child: tabbedView, color: Colors.black12);

darkcolorset

Mobile theme

    TabbedWiew tabbedView =
        TabbedWiew(controller: controller, theme: TabbedViewTheme.mobile());

mobile

Color set
    TabbedViewTheme theme = TabbedViewTheme.mobile(colorSet: Colors.blueGrey);
    TabbedWiew tabbedView = TabbedWiew(controller: controller, theme: theme);

mobilecolorset

Highlighted tab color
    TabbedViewTheme theme =
        TabbedViewTheme.mobile(highlightedTabColor: Colors.green[700]!);
    TabbedWiew tabbedView = TabbedWiew(controller: controller, theme: theme);

mobilehighlightedcolor

Minimalist theme

    TabbedWiew tabbedView =
        TabbedWiew(controller: controller, theme: TabbedViewTheme.minimalist());

minimalist

Color set
    TabbedWiew tabbedView = TabbedWiew(
        controller: controller,
        theme: TabbedViewTheme.minimalist(colorSet: Colors.blue));

minimalistchangecolor

Creating new theme #

It is possible to create an entire theme from scratch.

    var tabs = [
      TabData(text: 'Tab 1'),
      TabData(text: 'Tab 2'),
      TabData(text: 'Tab 3')
    ];

    TabbedViewTheme theme = TabbedViewTheme();
    theme.tabsArea
      ..border = Border(bottom: BorderSide(color: Colors.green[700]!, width: 3))
      ..middleGap = 6;

    Radius radius = Radius.circular(10.0);
    BorderRadiusGeometry? borderRadius =
        BorderRadius.only(topLeft: radius, topRight: radius);

    theme.tabsArea.tab
      ..padding = EdgeInsets.fromLTRB(10, 4, 10, 4)
      ..buttonsOffset = 8
      ..decoration = BoxDecoration(
          shape: BoxShape.rectangle,
          color: Colors.green[100],
          borderRadius: borderRadius)
      ..selectedStatus.decoration =
          BoxDecoration(color: Colors.green[200], borderRadius: borderRadius)
      ..highlightedStatus.decoration =
          BoxDecoration(color: Colors.green[50], borderRadius: borderRadius);

    TabbedWiew tabbedView =
        TabbedWiew(controller: TabbedWiewController(tabs), theme: theme);

fromthescratchcut

8
likes
130
pub points
23%
popularity

Publisher

caduandrade.net

Flutter widget inspired by the classic Desktop-style tab component. Supports customizable themes.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (LICENSE)

Dependencies

flutter

More

Packages that depend on tabbed_view