Flutter Material Bottom Navigation - Persistent Labels or Selected Label

In this tutorial, you will learn how to add persistent labels to a Material bottom navigation bar in Flutter. The persistent labels stay visible even when the navigation bar is not active, allowing users to quickly understand the navigation options available to them. 

We will go through a step-by-step process of creating a bottom navigation bar, implementing persistent labels, and adding navigation routes to each tab.

Bottom navigation with Persistent labels

Here's a step by step explanation of the code:

  • Import necessary packages:

import 'package:flutter/material.dart';

The material.dart package contains widgets and tools to implement the Material Design specification in Flutter.

..

  • Create a stateful widget:

class PersistentLabelsBottomNavigation extends StatefulWidget {
  const PersistentLabelsBottomNavigation({super.key});

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

This is a stateful widget that will contain the main logic and UI for the bottom navigation bar. 

It has a createState() method that returns an instance of PersistentLabelsBottomNavigationState, which will manage the widget's state.

..

  • Create the state class:

class PersistentLabelsBottomNavigationState
    extends State<PersistentLabelsBottomNavigation> {

This class extends the State class and has access to the properties and methods of PersistentLabelsBottomNavigation. It will contain the logic and UI for the bottom navigation bar.

..

  • Define the state variables:

int _selectedIndex = 0;

This variable will keep track of the current selected index of the bottom navigation bar.

static const List<Widget> _widgetOptions = <Widget>[
  Text(
    'Home',
    style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
  ),
  Text(
    'Search',
    style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
  ),
  Text(
    'Profile',
    style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
  ),
];

This is a list of widgets that will be displayed in the body of the scaffold, based on the current selected index of the bottom navigation bar.

..

  • Implement _onItemTapped method:

void _onItemTapped(int index) {
  setState(() {
    _selectedIndex = index;
  });
}

This method will be called when an item in the bottom navigation bar is tapped. It will update the _selectedIndex variable and call setState() to rebuild the UI.

..

  • Implement build method:

@override
Widget build(BuildContext context) {
  final colorScheme = Theme.of(context).colorScheme;
  final textTheme = Theme.of(context).textTheme;

  return Scaffold(
    body: Center(
      child: _widgetOptions.elementAt(_selectedIndex),
    ),
    bottomNavigationBar: BottomNavigationBar(
      showUnselectedLabels: true,
      selectedFontSize: textTheme.bodySmall!.fontSize!,
      unselectedFontSize: textTheme.bodySmall!.fontSize!,
      selectedItemColor: colorScheme.onPrimary,
      unselectedItemColor: colorScheme.onPrimary.withOpacity(0.38),
      backgroundColor: colorScheme.primary,
      currentIndex: _selectedIndex,
      onTap: _onItemTapped,
      type: BottomNavigationBarType.fixed,
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          label: 'Home',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.search),
          label: 'Search',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.person),
          label: 'Profile',
        ),
      ],
    ),
  );
}

This method builds the UI for the widget. It creates a scaffold with a body and a bottomNavigationBar

The body is a Center widget that displays the widget in _widgetOptions at the current selected index. 

The bottomNavigationBar is a BottomNavigationBar widget that displays the list of items with icons and labels. 

It uses the _selectedIndex variable to highlight

..

Full Source code:

import 'package:flutter/material.dart';

class PersistentLabelsBottomNavigation extends StatefulWidget {
  const PersistentLabelsBottomNavigation({super.key});

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

class PersistentLabelsBottomNavigationState
    extends State<PersistentLabelsBottomNavigation> {

  int _selectedIndex = 0; // current selected index of the bottom navigation bar

  // list of pages that correspond to each navigation bar item
  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Home',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
    Text(
      'Search',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
    Text(
      'Profile',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
  ];

  // callback function for when an item is tapped
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index; // update the selected index state variable
    });
  }

  @override
  Widget build(BuildContext context) {

    // get color and text themes from the current context
    final colorScheme = Theme.of(context).colorScheme;
    final textTheme = Theme.of(context).textTheme;

    return Scaffold(
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex), // display the page corresponding to the selected index
      ),
      bottomNavigationBar: BottomNavigationBar(
        // configure the appearance and behavior of the bottom navigation bar
        showUnselectedLabels: true,
        selectedFontSize: textTheme.bodySmall!.fontSize!,
        unselectedFontSize: textTheme.bodySmall!.fontSize!,
        selectedItemColor: colorScheme.onPrimary,
        unselectedItemColor: colorScheme.onPrimary.withOpacity(0.38),
        backgroundColor: colorScheme.primary,

        currentIndex: _selectedIndex, // set the current selected index
        onTap: _onItemTapped, // callback function for when an item is tapped
        type: BottomNavigationBarType.fixed,
        // create the list of navigation bar items
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: 'Search',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
        ],
      ),
    );
  }
}

..




..

Bottom Navigation - Selected Label

This tutorial will guide you through the process of implementing a bottom navigation bar with a selected label in your Flutter app. A bottom navigation bar is a commonly used UI pattern in mobile apps that allows the user to switch between different screens or sections of the app with a single tap. 

In this tutorial, you will learn how to create a bottom navigation bar with labels that change color when selected.

import 'package:flutter/material.dart';

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

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

class SelectedLabelsBottomNavigationState
    extends State<SelectedLabelsBottomNavigation> {
  int _selectedIndex = 0;

  // Define the widget options for each tab
  static const List<Widget> _widgetOptions = <Widget>[
    Text('Home',    style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold), ),
    Text('Search',  style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold), ),
    Text('Profile', style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold), ),
  ];


  // Handle the tap event for each tab
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(

        // Whether the labels are shown for the unselected
        showUnselectedLabels: false,

        // Set the selected tab index
        currentIndex: _selectedIndex,
        // Define the onTap event handler
        onTap: _onItemTapped,
        // Define the type of the bottom navigation bar
        type: BottomNavigationBarType.fixed,
        // Define the items in the bottom navigation bar
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            // Define the icon for the first tab
            icon: Icon(Icons.home),
            // Define the label for the first tab
            label: 'Home',
            // Define the color of the label when selected and unselected
            // based on the selected index
          ),
          BottomNavigationBarItem(
            // Define the icon for the second tab
            icon: Icon(Icons.search),
            // Define the label for the second tab
            label: 'Search',
            // Define the color of the label when selected and unselected
            // based on the selected index
          ),
          BottomNavigationBarItem(
            // Define the icon for the third tab
            icon: Icon(Icons.person),
            // Define the label for the third tab
            label: 'Profile',
          ),
        ],
      ),
    );
  }
}

..

Comments