Working with Tabs

Working with tabs is a common pattern in apps following the Material Design guidelines. Flutter includes a convenient way to create tab layouts as part of the material library.

Directions

  1. Create a TabController
  2. Create the tabs
  3. Create content for each tab

1. Create a TabController

In order for tabs to work, we’ll need to keep the selected tab and content sections in sync. This is the job of the TabController.

We can either manually create a TabController or use the DefaultTabController Widget. Using the DefaultTabController is the simplest option, since it will create a TabController for us and make it available to all descendant Widgets.

DefaultTabController(
  // The number of tabs / content sections we need to display
  length: 3,
  child: // See the next step!
);

2. Create the tabs

Now that we have a TabController to work with, we can create our tabs using the TabBar Widget. In this example, we’ll create a TabBar with 3 Tab Widgets and place it within an AppBar.

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      bottom: TabBar(
        tabs: [
          Tab(icon: Icon(Icons.directions_car)),
          Tab(icon: Icon(Icons.directions_transit)),
          Tab(icon: Icon(Icons.directions_bike)),
        ],
      ),
    ),
  ),
);

By default, the TabBar looks up the Widget tree for the nearest DefaultTabController. If you’re manually creating a TabController, you’ll need to pass it to the TabBar.

3. Create content for each tab

Now that we have tabs, we’ll want to display content when a tab is selected. For this purpose, we’ll employ the TabBarView Widget.

Note: Order is important and must correspond to the order of the tabs in the TabBar!

TabBarView(
  children: [
    Icon(Icons.directions_car),
    Icon(Icons.directions_transit),
    Icon(Icons.directions_bike),
  ],
);

Complete example

import 'package:flutter/material.dart';

void main() {
  runApp(TabBarDemo());
}

class TabBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              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),
            ],
          ),
        ),
      ),
    );
  }
}

Tabs Demo