Creating a Custom Curved Navigation Bar in Flutter
Tags: flutter, mobile, flutterdev, tutorial
Published: 2023-06-10 15:27:53

**Introduction:**
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

**Prerequisites:**
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xworogsjm1p830gxj5cw.png)


**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yffd650ky6cse9279nue.png)


**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ge1ipdae5bbhtvro333c.png)


**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65a85iwxqbp388ue64ih.png)


**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<Path>. Inside the getClip method, we will define the curved shape using Path operations.


![Custom Curved Navigation Bar in Flutter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/79d90dwr3ogguy2n6yjg.png)


**A Little Sauce**

![Custom Curved Navigation Bar in Flutter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yu6jrgjjzisl1x8ytczi.png)



**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2rvo42h9ro28fvk4pj4.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ngov68dxsubaukpdwe7b.png)


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

class CurvedNavigationBar extends StatelessWidget {
  const CurvedNavigationBar({
    Key? key,
    required this.items,
    this.onTap,
    this.unselectedColor = Colors.grey,
    this.selectedColor = Colors.blue,
    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;

  @override
  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,
    this.selectedIconData,
  });

  final IconData iconData;
  final IconData? selectedIconData;
}

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

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

```

_> 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_

**Conclusion:**

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/586ez5bye5ez6apevyzz.png)


> Updated !!!: Check out the new update with in my gitub repo:
> [Github Repo](https://github.com/black-coda/nike_shoe_shop/blob/main/lib/src/utils/custom_curved_nav_bar.dart)