Flutter Tabs

Flutter Tabs Tutorial and Examples

Exploring the classes required to create tabs in flutter.

Tab derives from the StatelessWidget:

class Tab extends StatelessWidget

Tab also resides in the flutter package.

If both icon and text are provided, the text is displayed below the icon.

Let’s start by introducing some APIs we will be using while constructing our Tabs.

1. TabView

TabBarView is a page view that displays the widget which corresponds to the currently selected tab. Typically used in conjunction with a TabBar.

TabBarView is a concrete class and derives from the StatefulWidget class.

class TabBarView extends StatefulWidget

Think of this as the page that actually renders your widgets when you click or swipe to a given tab.

The tabBarView as well as the TabBar are normally cordinated by the TabController.

However if a TabController is not provided, you use the DefaultTabController.

 

2. TabBar

TabBar is a material design widget that displays a horizontal row of tabs.

class TabBar extends StatefulWidget implements PreferredSizeWidget

TabBar resides in the flutter package.

Mostly TabBar is created as the AppBar.bottom part of an AppBar and in conjunction with a TabBarView.

And if you don’t provide a tabcontroller that will cordinate the tabbar and tabview, then you can use DefaultTabController instead.

Make sure your tab controller’s TabController.length is the same as the length of the tabs list.

3. TabBarController

TabController is a class that coordinates tab selection between a TabBar and a TabBarView.

Here’s it’s definition:

class TabController extends ChangeNotifier

This widget is important when you want to work with tabs.

You can get the position of the selected tab via the index property of this class. When you swipe or scroll or click a tab, we animate to the clicked tab, the selected tab’s index can be changed with animateTo.

A stateful widget that builds a TabBar or a TabBarView can create a TabController and share it directly.

When the TabBar and TabBarView don’t have a convenient stateful ancestor, a TabController can be shared by providing a DefaultTabController inherited widget.

Here’s an example of TabController in use:

class MyTabbedPage extends StatefulWidget {
  const MyTabbedPage({ Key key }) : super(key: key);
  @override
  _MyTabbedPageState createState() => new _MyTabbedPageState();
}

class _MyTabbedPageState extends State<MyTabbedPage> with SingleTickerProviderStateMixin {
  final List<Tab> myTabs = <Tab>[
    new Tab(text: 'LEFT'),
    new Tab(text: 'RIGHT'),
  ];

  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = new TabController(vsync: this, length: myTabs.length);
  }

 @override
 void dispose() {
   _tabController.dispose();
   super.dispose();
 }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        bottom: new TabBar(
          controller: _tabController,
          tabs: myTabs,
        ),
      ),
      body: new TabBarView(
        controller: _tabController,
        children: myTabs.map((Tab tab) {
          return new Center(child: new Text(tab.text));
        }).toList(),
      ),
    );
  }
}

4. DefaultTabBarController

DefaultTabController is the TabController for descendant widgets that don’t specify one explicitly.

DefaultTabController derives from the StatefulWidget. This implies it has a mutable state.

class DefaultTabController extends StatefulWidget

DefaultTabController is an inherited widget that is used to share a TabController with a TabBar or a TabBarView.

It’s used when sharing an explicitly created TabController isn’t convenient because the tab bar widgets are created by a stateless parent widget or by different parent widgets.

class MyDemo extends StatelessWidget {
  final List<Tab> myTabs = <Tab>[
    new Tab(text: 'LEFT'),
    new Tab(text: 'RIGHT'),
  ];

  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: myTabs.length,
      child: new Scaffold(
        appBar: new AppBar(
          bottom: new TabBar(
            tabs: myTabs,
          ),
        ),
        body: new TabBarView(
          children: myTabs.map((Tab tab) {
            return new Center(child: new Text(tab.text));
          }).toList(),
        ),
      ),
    );
  }
}
Share

1 Example

  1. This answer was edited.

    Flutter Swipe Tabs

    Here is a simple swipe tabs example using Flutter. You swipe through pages with each containing an image.

    Let’s start.

    (a). first.dart

    Create a Dart class to represent the first tab. The class will extend a statelesswidget.

    import 'package:flutter/material.dart';
    
    class First extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Container(
          child: new Center(
            child: new Column(
              // center the children
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Icon(
                  Icons.favorite,
                  size: 160.0,
                  color: Colors.red,
                ),
                new Text("First Tab")
              ],
            ),
          ),
        );
      }
    }
    

     

    (b). second.dart

    This is the second tab. Like all other tabs, it is a statelesswidget.

    import 'package:flutter/material.dart';
    
    class Second extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Container(
          child: new Center(
            child: new Column(
              // center the children
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Icon(
                  Icons.adb,
                  size: 160.0,
                  color: Colors.green,
                ),
                new Text("Second Tab")
              ],
            ),
          ),
        );
      }
    }
    

     

    (c). third.dart

    Then the final tab:

    import 'package:flutter/material.dart';
    
    class Third extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Container(
          child: new Center(
            child: new Column(
              // center the children
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Icon(
                  Icons.airport_shuttle,
                  size: 160.0,
                  color: Colors.blue,
                ),
                new Text("Third Tab")
              ],
            ),
          ),
        );
      }
    }
    

     

    (d). main.dart

    Finally the last class is the main.dart, which will contain the entry point to our application, the main() method.

    Here is the code for this:

    import 'package:flutter/material.dart';
    import 'package:using_tabs/tabs/first.dart';
    import 'package:using_tabs/tabs/second.dart';
    import 'package:using_tabs/tabs/third.dart';
    
    void main() {
      runApp(new MaterialApp(
        // Title
          title: "Using Tabs",
          // Home
          home: new MyHome()));
    }
    
    class MyHome extends StatefulWidget {
      @override
      MyHomeState createState() => new MyHomeState();
    }
    
    // SingleTickerProviderStateMixin is used for animation
    class MyHomeState extends State<MyHome> with SingleTickerProviderStateMixin {
      /*
       *-------------------- Setup Tabs ------------------*
       */
      // Create a tab controller
      TabController controller;
    
      @override
      void initState() {
        super.initState();
    
        // Initialize the Tab Controller
        controller = new TabController(length: 3, vsync: this);
      }
    
      @override
      void dispose() {
        // Dispose of the Tab Controller
        controller.dispose();
        super.dispose();
      }
    
      TabBar getTabBar() {
        return new TabBar(
          tabs: <Tab>[
            new Tab(
              // set icon to the tab
              icon: new Icon(Icons.favorite),
            ),
            new Tab(
              icon: new Icon(Icons.adb),
            ),
            new Tab(
              icon: new Icon(Icons.airport_shuttle),
            ),
          ],
          // setup the controller
          controller: controller,
        );
      }
    
      TabBarView getTabBarView(var tabs) {
        return new TabBarView(
          // Add tabs as widgets
          children: tabs,
          // set the controller
          controller: controller,
        );
      }
    
      /*
       *-------------------- Setup the page by setting up tabs in the body ------------------*
       */
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          // Appbar
            appBar: new AppBar(
              // Title
                title: new Text("Using Tabs"),
                // Set the background color of the App Bar
                backgroundColor: Colors.blue,
                // Set the bottom property of the Appbar to include a Tab Bar
                bottom: getTabBar()),
            // Set the TabBar view as the body of the Scaffold
            body: getTabBarView(<Widget>[new First(), new Second(), new Third()]));
      }
    }
    

    Run

    To run the project just copy the 4 files into your project. There is nothing special about. Just note that the tab classes are contained in a folder known as `tabs`.

    Here is what you will get:

    Flutter Tabs

    Flutter Swipe Tabs example

    Special thanks to @nisrulz for creating this example.




Share an Example

Share an Example

Browse
What is the capital of Egypt? ( Cairo )