How to Implement Tabs in Flutter.

Credit: Pexels.com | Expect Best

Howdy, today I am going to cover how to implement a tab in your flutter app. I am going to expand my project from the last blog post I made. This time, I’m just going to add a new tab for future blogs and fill it with content. Let’s get started!

On this blog I am going to use the Tab in Material Design.

Material Design Tab

Tabs organize and facilitate navigation between related and, at the same level of hierarchy, groupings of material. Furthermore, there are two types of tabs. “fixed tabs” and “scrollable tabs”. We are going to use “fixed tabs” on this blog. On the contrary, fixed tabs show all tabs on one screen, each with a fixed width. The width of each tab is calculated by dividing the number of tabs by the width of the screen. They do not scroll to expose more tabs; the displayed tab set is the only one available.

You can check out the docs here: https://material.io/components/tabs/flutter#fixed-tabs

Application

For instance, here’s the source code of my project. I am going to implement Material Tabs in it.

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.amber,
        title: Text('Todo'),
      ),
      body: TodoList(),
    );
  }
}

class TodoList extends StatefulWidget {
  const TodoList({Key? key}) : super(key: key);

  @override
  State<TodoList> createState() => _TodoListState();
}

class _TodoListState extends State<TodoList> {
  List<dynamic> data = <dynamic>[];
  bool valid = true;
  void getData() async {
    try{
      Response response = await get(
      Uri.parse('https://jsonplaceholder.typicode.com/todos'),
    );

    data = jsonDecode(response.body);
    }catch (e) {
      setState(() {
        valid = false;
      });
    }
    
    // print(data); // will print a list of datasets
  }

  @override
  Widget build(BuildContext context) {
    getData();
    return Visibility(
      child: Center(
        child: ListView.builder(
            itemCount: data.length, // assign length of the data here
            itemBuilder: (context, index) {
              // returns a Card widget
              return Card(
                child: ListTile(
                  leading: Text(
                    data[index]['id'].toString(), // assigned data's id here
                    style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                  ),
                  title: Text(
                    data[index]['title'], // assigned data's title here
                  ),
                  trailing: CupertinoSwitch(
                    value: data[index]
                        ['completed'], // assigned data's completed status here
                    onChanged: (bool status) {},
                    activeColor: Colors.amber,
                  ),
                ),
              );
            }),
      ),
      replacement: const SizedBox(
        height: 50,
        child: Center(
          child: Text(
                      "Cannot load data",
                      style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                    ),
        ),
      ),
      visible: valid,
    );
  }
}

In the first place I am going to wrap the HomePage widget of my app with “DefaultTabController” widget and define the number of tabs I want to make in the app by assigning 2 in the length argument. As a result, I have to make a widget called “TabBar” in the bottom argument of my “HomePage” widget with Tab widget assigned in the “tabs” argument. Furthermore, in the body argument of the “HomePage” widget I also have to wrap the contents in “TabBarView” widget.

Check the full application code below:

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: DefaultTabController(length: 2, child: HomePage()),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.amber,
        title: const Text('To-Do App'),
        bottom: const TabBar(indicatorColor: Colors.white, tabs: [
          Tab(
            text: 'Todo',
            icon: Icon(Icons.note),
          ),
          Tab(
            text: 'Gallery',
            icon: Icon(Icons.image),
          ),
        ]),
      ),
      body: TabBarView(children: [
        const TodoList(),
        Text('Tab Content here'),
      ]),
    );
  }
}

class TodoList extends StatefulWidget {
  const TodoList({Key? key}) : super(key: key);

  @override
  State<TodoList> createState() => _TodoListState();
}

class _TodoListState extends State<TodoList> {
  List<dynamic> data = <dynamic>[];
  bool valid = true;
  void getData() async {
    try {
      Response response = await get(
        Uri.parse('https://jsonplaceholder.typicode.com/todos'),
      );

      data = jsonDecode(response.body);
    } catch (e) {
      setState(() {
        valid = false;
      });
    }

    //  print(data); // will print a list of datasets
  }

  @override
  Widget build(BuildContext context) {
    getData();
    return Visibility(
      child: Center(
        child: ListView.builder(
            itemCount: data.length, // assign length of the data here
            itemBuilder: (context, index) {
              // returns a Card widget
              return Card(
                child: ListTile(
                  leading: Text(
                    data[index]['id'].toString(), // assigned data's id here
                    style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                  ),
                  title: Text(
                    data[index]['title'], // assigned data's title here
                  ),
                  trailing: CupertinoSwitch(
                    value: data[index]
                        ['completed'], // assigned data's completed status here
                    onChanged: (bool status) {},
                    activeColor: Colors.amber,
                  ),
                ),
              );
            }),
      ),
      replacement: const SizedBox(
        height: 50,
        child: Center(
          child: Text(
            "Cannot load data",
            style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
          ),
        ),
      ),
      visible: valid,
    );
  }
}

Conclusion

To conclude, we’ve covered how to add tabs in your Flutter app using Material Design’s tab widget in doing so we had to implement a widget called “DefaultTabController”, “TabBar”, and “TabBarView” to make it work. Thank you for reading.

Leave a Comment

Your email address will not be published. Required fields are marked *