DEV Community

Cover image for Creating a Custom Curved Navigation Bar in Flutter
Monday Solomon
Monday Solomon

Posted on • Updated on

Creating a Custom Curved Navigation Bar in Flutter

Flutter is a popular cross-platform framework for building beautiful and interactive mobile applications. One of the essential components of many mobile apps is a navigation bar that allows users to navigate between different sections or screens. In this tutorial, we will learn how to create a custom curved navigation bar in Flutter.

Table of Contents

  • Prerequisites
  • Setting Up the Project
  • Creating the CurvedNavigationBar Widget
  • Defining Navigation Items
  • Styling the Navigation Bar
  • Implementing Tap Callbacks
  • Clipping the Container
  • Summary
  • Conclusion

Before we begin, make sure you have Flutter installed on your machine and have a basic understanding of Flutter concepts.

Setting Up the Project:
To start, create a new Flutter project using your preferred IDE or by running the following command in your terminal:

flutter create curved_navigation_bar

Creating the CurvedNavigationBar Widget:

In Flutter, we can create reusable widgets to encapsulate specific functionality. Let's define a new widget called CurvedNavigationBar by creating a new file named curved_navigation_bar.dart in the lib directory of your project.

Custom Curved Navigation Bar in Flutter

Defining Navigation Items:

To configure the navigation items for our curved navigation bar, we will create another class called CurvedNavigationBarItem. Each item will consist of an IconData for the default icon and an optional IconData for the selected state. We will define these classes in the same curved_navigation_bar.dart file

Custom Curved Navigation Bar in Flutter

Styling the Navigation Bar:

In the CurvedNavigationBar widget, we will use a Row widget to arrange the navigation items horizontally. We will also specify the colors for the selected and unselected states.

Custom Curved Navigation Bar in Flutter

Implementing Tap Callbacks:

To handle tap events on the navigation items, we will pass a callback function called onTap to the CurvedNavigationBar widget. Inside the Row widget, we will wrap each navigation item with an IconButton and set the onPressed property to call the onTap callback with the corresponding index.

Custom Curved Navigation Bar in Flutter

Clipping the Container:
To achieve the curved shape for our navigation bar, we will use the ClipPath widget. We will create a custom clipper called _CurvedClipper by extending CustomClipper. Inside the getClip method, we will define the curved shape using Path operations.

Custom Curved Navigation Bar in Flutter

A Little Sauce

Custom Curved Navigation Bar in Flutter

Summary of the codes

The code defines a custom curved navigation bar widget in Flutter. The navigation bar has a curved shape and contains a row of icons. Here's a breakdown of the code:

  1. The CurvedNavigationBar widget is the main widget that represents the curved navigation bar. It takes the following parameters:

    • items: a list of CurvedNavigationBarItem objects representing the navigation items.
    • onTap: a callback function to handle the tap event on the navigation items.
    • unselectedColor: the color of unselected navigation items.
    • selectedColor: the color of the selected navigation item.
    • currentIndex: the index of the currently selected item.
  2. The CurvedNavigationBarItem class represents a single item in the navigation bar. It contains the iconData property for the default icon and the selectedIconData property for the icon when the item is selected.

  3. The _CurvedClipper class is a custom CustomClipper that defines the curved shape of the navigation bar using the getClip method. It creates a path with a quadratic Bezier curve and lines to form the curved shape.

  4. In the build method of the CurvedNavigationBar widget, the navigation bar is constructed using a ClipPath and a Container. The navigation items are generated using a Row and IconButton widgets. The selected and unselected colors are applied based on the currentIndex.

  5. The Padding widget is used to add spacing at the bottom of the first and last navigation items.

To use this custom curved navigation bar, you can create an instance of CurvedNavigationBar and provide the necessary parameters. For example:

Custom Curved Navigation Bar in Flutter

Note: Make sure to import the necessary dependencies and define the PhotoAppColors class to use the desired colors.

Entire Code

Custom Curved Navigation Bar in Flutter

import 'package:flutter/material.dart';

class CurvedNavigationBar extends StatelessWidget {
  const CurvedNavigationBar({
    Key? key,
    required this.items,
    this.unselectedColor = Colors.grey,
    this.selectedColor =,
    this.currentIndex = 0,
  })  : assert(
          items.length == 4,
          'The correct functioning of this widget '
          'depends on its items being exactly 4',
        super(key: key);

  final List<CurvedNavigationBarItem> items;
  final ValueChanged<int>? onTap;
  final Color unselectedColor;
  final Color selectedColor;
  final int currentIndex;

  Widget build(BuildContext context) {
    return ClipPath(
      clipper: _CurvedClipper(),
      child: Container(
        alignment: const Alignment(0, 1.6),
        height: kToolbarHeight * 1.5,
        color: Colors.white,
        padding: const EdgeInsets.symmetric(horizontal: 30),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: List.generate(items.length, (index) {
            final item = items[index];
            return Padding(
              padding: EdgeInsets.only(
                bottom: (index == 0 || index == 3) ? 20.0 : 0,
              child: IconButton(
                onPressed: () => onTap?.call(index),
                color: index == currentIndex ? selectedColor : unselectedColor,
                icon: Icon(
                  index == currentIndex
                      ? item.selectedIconData ?? item.iconData
                      : item.iconData,
            ..insert(2, const SizedBox()),

class CurvedNavigationBarItem {
  const CurvedNavigationBarItem({
    required this.iconData,

  final IconData iconData;
  final IconData? selectedIconData;

class _CurvedClipper extends CustomClipper<Path> {
  Path getClip(Size size) {
    return Path()
      ..quadraticBezierTo(size.width * .5, kToolbarHeight, size.width, 0)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height);

  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;

Enter fullscreen mode Exit fullscreen mode

_> The code overrides the build method of the CurvedNavigationBar widget and returns a widget tree.

The ClipPath widget is used to clip the container with a custom shape defined by the CurvedClipper class.
Inside the Container, the alignment property is set to Alignment(0, 1.6) to align the contents at the bottom of the container.
The height property is set to kToolbarHeight * 1.5 to determine the height of the navigation bar,
kToolbarHeight is a predefined height constant in Flutter.
The color property is set to Colors.white to give the navigation bar a white background color.
The padding property is set to provide horizontal spacing for the navigation item


In this tutorial, we learned how to create a custom curved navigation bar in Flutter. We defined a CurvedNavigationBar widget and configured its navigation items, styling, and tap callbacks. We also used a custom clipper to create the curved shape for the navigation bar. By following these steps, you can easily create your own custom navigation bar with a curved design to enhance the user experience of your Flutter applications.

That's it! With the custom curved navigation bar implemented, you can further customize it by adjusting colors, icons, and adding animations to create a unique and visually appealing user interface. Feel free to explore more possibilities and incorporate this navigation bar into your Flutter projects. Happy coding!

Expected output:

Image description

Updated !!!: Check out the new update with in my gitub repo:
Github Repo

Top comments (0)