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.

Flutter Tutorial: Beautiful Flutter App Bar Widget Customization

Flutter Tutorial: Beautiful Flutter...
Flutter Tutorial: Beautiful Flutter App Bar Widget Customization

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(),
        ),
      ),
    );
  }
}

Example 1: Simple Tabs Example

Here is the demo screenshot of this example:

Flutter Tabs Example

This example will comprise the following files:

  • appbar_bottom.dart

Step 1: Create Project.

  1. Open your favorite Flutter IDE.
  2. Go to File-->New-->Project to create a new project.

Step 2: Dependencies.

No external dependencies are needed for this project.

Step 4: Write Dart Code

Write your code as follows:

*(a). appbar_bottom.dart

Create a file Dart named appbar_bottom.dart

Here is the full code

import 'package:flutter/material.dart';

class AppBarBottom extends StatefulWidget {
  final String title;

  const AppBarBottom(this.title);

  @override
  _AppBarBottomState createState() => _AppBarBottomState();
}

class _AppBarBottomState extends State<AppBarBottom>
    with SingleTickerProviderStateMixin {
  TabController? _tabController;

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(48),
          child: Container(
            color: Colors.white,
            height: 48,
            alignment: Alignment.center,
            child: TabPageSelector(controller: _tabController),
          ),
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: <Widget>[
          Container(
            color: Colors.orangeAccent,
          ),
          Container(
            color: Colors.redAccent,
          ),
          Container(
            color: Colors.blueAccent,
          ),
        ],
      ),
    );
  }
}

Run

Simply copy the source code into your Flutter Project, Build and Run.

Reference.

Download code here.
Follow code author here.

Example 2: Flutter Swipe Tabs with Cards

Flutter Swipe Tabs with Cards Tutorial.

This is a flutter Swipe Tabs tutorial. How to switch through cards containing images by swiping forward or backwards or clicking the tabs.

We will have 6 Tabs in our application. The Tabs will be arranged beautifully in our appBar just below the title.

Each tab will have the tab title and icon. You can then click the tab or swipe it either from left to right or right to left.

Our TabViews will have Cards.Each Card will have an image and text.

Video Tutorial(ProgrammingWizards TV Channel)

Well we have a video tutorial as an alternative to this. If you prefer tutorials like this one then it would be good you subscribe to our YouTube channel.

Basically we have a TV for programming where do daily tutorials especially android.

Let's look a flutter swipe tabs example with cards.

Flutter Swipe tabs with Cards Example

This is a simple flutter swipe tabs example.We use Dart programming language.

Flutter Swipe Tabs

Flutter Swipe Tabs

Here are the files we explore:

  1. pubspec.yaml
  2. lib/main.dart
(a). pubspec.yaml
name: mr_tabs
description: A new Flutter application.

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #  - images/a_dot_burr.jpeg
  #  - images/a_dot_ham.jpeg
(b). main.dart

This is where we write our flutter code in dart programming language. In Dart it is very common to write several classes in a single file. So this simple file will have three classes.

Importing Packages in Flutter/Dart

But first we need to import some packages and we do that using the import keyword in dart.

import 'package:flutter/material.dart';

Here are the packages we are importing:

  1. material.dart : will give us material design widgets and theme.
    .
Creating classes in Flutter/Dart

In Dart like in most C style programming languages you create a class using the class keyword. Classes are encapsulation mechanism in Object Oriented Programming languages.

In this case we create three classes:
1.class Category{..}

  1. class MrTabs extends StatelessWidget {..}
  2. class CategoryCard extends StatelessWidget {..}
import 'package:flutter/material.dart';

//Our Category Data Object
class Category {
  const Category({ this.name, this.icon });
  final String name;
  final IconData icon;
}

// List of Category Data objects.
const List<Category> categories = <Category>[
  Category(name: 'General', icon: Icons.assessment),
  Category(name: 'Tech', icon: Icons.code),
  Category(name: 'Lifestyle', icon: Icons.people),
  Category(name: 'Finance', icon: Icons.account_balance),
  Category(name: 'Education', icon: Icons.school),
  Category(name: 'Sports', icon: Icons.settings_input_composite),
];

// Our MrTabs class.
//Will build and return our app structure.
class MrTabs extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new DefaultTabController(
        length: categories.length,
        child: new Scaffold(
          appBar: new AppBar(
            title: const Text('Tabbed AppBar'),
            bottom: new TabBar(
              isScrollable: true,
              tabs: categories.map((Category choice) {
                return new Tab(
                  text: choice.name,
                  icon: new Icon(choice.icon),
                );
              }).toList(),
            ),
          ),
          body: new TabBarView(
            children: categories.map((Category choice) {
              return new Padding(
                padding: const EdgeInsets.all(16.0),
                child: new CategoryCard(choice: choice),
              );
            }).toList(),
          ),
        ),
      ),
       theme: new ThemeData(primaryColor: Colors.deepOrange),
    );
  }
}

// Our CategoryCard data object
class CategoryCard extends StatelessWidget {
  const CategoryCard({ Key key, this.choice }) : super(key: key);
  final Category choice;

  //build and return our card with icon and text
  @override
  Widget build(BuildContext context) {
    final TextStyle textStyle = Theme.of(context).textTheme.display1;
    return new Card(
      color: Colors.white,
      child: new Center(
        child: new Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            new Icon(choice.icon, size: 128.0, color: textStyle.color),
            new Text(choice.name, style: textStyle),
          ],
        ),
      ),
    );
  }
}
// Our main method
void main() {
  runApp(new MrTabs());
}

Download

You can download full source code below.

No. Location Link
1. GitHub Direct Download
2. GitHub Browse

Example 3: Flutter Nested TabBar

This is a nested tabs example project.

This is great if you want tabs with probably a header on top of them. Normally tabs are displayed at the bottom of the appBar. What about if you want to include say an image or some card between the tabbar and appbar. This is what we create.

We will in the process understand around 4 classes that are mandatory for creating tabs:

  1. TabController/DefaultTabController.
  2. TabBar
  3. TabView
  4. Tab

Let's start.

Video tutorial(ProgrammingWizards TV Channel)

Well we have a video tutorial as an alternative to this. If you prefer tutorials like this one then it would be good you subscribe to our YouTube channel. Basically we have a TV for programming where do daily tutorials especially android.

Flutter Nested Tabs Example

This is a flutter nested tabs example. We will have a container on top of our TabBar. That container can of course contain anything like say an image or some text.

Here's the example:

Flutter Nested Tabs

Flutter Nested Tabs

Then below it we have our tabs using the DefaultTabController. We will give them a dark them.

Here are the things to note.

  1. The container on top of our tabbar can contain any widget.
  2. Our Tabs will be clickable and swipeable.

Dart Concepts we Learn in This Tutorial

You can use this tutorial even if you have never tasted Dart before.

Here are the important concepts to get you started:

1. Importing Packages in Flutter/Dart

But first we need to import some packages and we do that using the import keyword in dart.

We do that using the import keyword, similar to java.

You use import to specify how a namespace from one library is used in the scope of another library.
Remember every Dart app is a library,even if it doesn’t use a library directive.

To import a given library, the only required argument is a URI specifying the library.

If the library is a built-in/standard one, then the URI has the special dart: scheme. For other libraries, you can use a file system path or the package: scheme. The package: scheme specifies libraries provided by a package manager such as the pub tool.

For in our example here:

import 'package:flutter/material.dart';
import 'package:flutter_date_picker/flutter_date_picker.dart';

Here are the packages we are importing:

  1. material.dart : will give us material design widgets and theme.
  2. flutter_date_picker.dart : Will give us DatePicker to work get and set dates with.

2. Classes and Object in Flutter/Dart

In Dart like in most C style programming languages you create a class using the class keyword. Classes are encapsulation mechanism in Object Oriented Programming languages.

An object on the other hand is an instance of a class and all classes descend from Object.

To create an object, you can use the new keyword with a constructor for a class. Constructor names can be either ClassName or ClassName.identifier:

var myApp = new MyApp(); // Create a MyApp object using MyApp().

In this case we create three classes:

  1. class MyApp...
  2. class Home...

4. Class Inheritance in Dart

Inheritance is an object oriented pillar, one of the main ones. And Dart definitely supports it fully. Inheritance provides alot of power to programming languages like Dart as it allows one class to derive properties and methods of another.

In Dart to implement inheritance you use the extends keyword just like in java.
Here are the keywords you may see in this tutorial:

  1. extends - creates a subclass.
  2. super - refers to the superclass or parent class.

Here are examples

  1. class MyApp extends StatelessWidget {..}
  2. class Home extends StatefulWidget {..}

3. Class-Level vs Top Level Functions

Class Level Functions, typically known as methods, are methods confined inside a class and belonging either to the instance of the class or the class itself. Top Level functions are not confined to any class.

Dart supports different function types like:

  • Top level functions like the main()),
  • Static Functions - That is functions tied to a class.
  • Instance Methods -Functions tied to an object.
  • Nested or Local Functions : functions within functions.

Here's our top level main function:

void main() => runApp(MyApp());

4. The main method in Dart

In Dart, like in Java and C#, the entry point to an application is the famous main() method. When your application starts, the main() method gets invoked first and when it finishes the app also finishes.

In our case we run our app in the main method.

void main() => runApp(MyApp());

5. Fat Arrow Shorthand Syntax in Dart

Dart is a language that allows you write short concise and compact code. One of the features it provides is the fat arror shorthand syntax.

For functions that contain just one expression, you can use this shorthand syntax.

For example instead of this:

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

You can write this:

void main() => runApp(MyApp());
[notice] Only an expression and not a statement can appear between the arrow
(=>) and the semicolon (;).
[/notice]

6. In Dart Functions are First-Class Objects

This means you can pass a function as a parameter to another function.

For example:

showNumber(myNumber) {
    print(myNumber);
}
var myNumbers = [1,2,3];
myNumbers.forEach(showNumber); // Pass showNumber as a parameter.

7. In Dart All functions return a value.

Yeah. If no return value is specified, the statement return null; is implicitly appended to the function body.

8. If and Else in Dart
Dart supports if statements with optional else statements.

if (engineRunning()) {
    jet.fly();
} else if (engineStopped()) {
    jet.restartEngine();
} else {
    jet.repairEngine();
}

9. For Loops in Dart
Like many languages, in dart you can iterate with the standard for loop.

for (int i = 0; i < galaxies.length; i++) {
    print(galaxies[i].getName());
}

Closures inside of Dart's for loops capture the value of the index, avoiding a co
pitfall found in JavaScript. For example, consider:

var callbacks = [];
for (var i = 0; i < 2; i++) {
    callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());

The output is 0 and then 1, as expected. In contrast, the example would print 2 and then 2 in JavaScript.

If the object that you are iterating over is a Collection, you can use the forEach() method. That is if you don't need to know the current iteration counter:

galaxies.forEach((galaxy) => galaxy.getName());

Collections also support the for-in form of iteration:

var collection = [0, 1, 2];
for (var planet in planets) {
    print(planet);
}

Flutter API's we use in this Project

We are using Dart specifically to write flutter apps. You can target either Android or iOS.

Let's look at some of the APIs we will be using in this project

1. Widget

A Widget is an abstract class in flutter package that describes the configuration for an Element.

Widgets are the central class hierarchy in the Flutter framework. A widget is an immutable description of part of a user interface. Widgets can be inflated into elements, which manage the underlying render tree.

We will be implementing two Widget sub-classes in this class:

  1. StatelessWidget
  2. StatefulWidget

This this will allow us override the build() method hence returning a Widget object:

class MyApp extends SomeWidget
  @override
  Widget build(BuildContext context) {
      return our_widget;
  }

The build() method describes the part of the user interface represented by this widget.

Read more about Widget here.

2. StatelessWidget

A statelesswidget widget is an abstract class that represents a widget that does not require mutable state.

Read more about StatelessWidget here.

3. BuildContext

A BuildContext is a handle to the location of a widget in the widget tree.

It's an abstract class that presents a set of methods that can be used from StatelessWidget.build methods and from methods on State objects.

Read more about BuildContext here.

5. MaterialApp

MaterialApp is a class that represents an application that uses material design.

Read more about MaterialApp here.

6. ThemeData

ThemeData is a class that holds the color and typography values for a material design theme.

Read more about ThemeData here.

7. DefaultTabController

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

DefaultTabController derives from the StatefulWidget and has a mutable state.

Read more about DefaultTabController here.

8. TabBar

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

Read more about TabBar here.

9. TabBarView

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

Read more about TabBarView here.

10. Tab

A material design TabBar tab.

Read more about Tab here.

Here are the files we explore:

  1. pubspec.yaml
  2. lib/main.dart

(a). pubspec.yaml

Flutter supports using shared packages contributed by other developers to the Flutter and Dart ecosystems. This allows you to quickly build your app without having to develop everything from scratch.

We will be adding packages under this file.

  1. Open the pubspec.yaml file located inside your app folder, and add dependencies under dependencies.
  2. If it is a third party then you have to install it.
    From the terminal: Run flutter packages get

OR

From Android Studio/IntelliJ: Click 'Packages Get' in the action ribbon at the top of pubspec.yaml
From VS Code: Click 'Get Packages' located in right side of the action ribbon at the top of pubspec.yaml

flutter is always our sdk dependency as we use it to develop our ios and android apps.

Here's our pubspec.yaml file:

name: nested_tabbar
description: A new Flutter project.

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

Take note we are not using any third party dependency in our app.

(b). main.dart

This is where we write our flutter code in dart programming language. In Dart it is very common to write several classes in a single file. So this simple file will have three classes.

Full Code

here's the full main.dart code:

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Mr Nested TabBar',
        theme: ThemeData(brightness: Brightness.dark),
        home: Scaffold(body: HomePage()));
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(children: [
      Container(
          color: Colors.orangeAccent,
          height: 150.0,
          child: Center(child: Text('Something'))),
      DefaultTabController(
          length: 2,
          initialIndex: 0,
          child: Column(
            children: [
              TabBar(tabs: [Tab(text: 'Home'), Tab(text: 'News')]),
              Container(
                  height: 300.0,
                  child: TabBarView(
                    children: [
                      Center(child: Text('Home here')),
                      Center(child: Text('News here')),
                      ],
                  ))
            ],
          ))
    ]);
  }
}

// Our top level main function
void main() => runApp(new MyApp());
//end

(c) Running Flutter Applications

Just make sure you device or emulator is running and click the run button in android studio, it will automatically pick the device and install the app.

Aletrnative you can use the terminal or command prompt. Navigate/Cd over to project root page and type this:

flutter.bat build apk

This will build the APK which you can then drag and install onto your device. The build process in my machine takes around three minutes which is not bad.

Download

You can download full source code below.

No. Location Link
1. GitHub Direct Download
2. GitHub Browse