Implementing Rounded and Curved Bottom Navigation Bars in Flutter

Introduction
Flutter provides a flexible and powerful framework for building beautiful and engaging user interfaces. In this article, we’ll explore how to implement two distinct styles of bottom navigation bars: a rounded variant and a curved variant. These navigation bars not only enhance the visual appeal of your app but also demonstrate the customization capabilities of Flutter.
Prerequisites
Before we dive into the implementation, make sure you have Flutter installed and a basic understanding of Flutter widgets and navigation concepts.
Part 1: Rounded Bottom Navigation Bar
Step 1: Set Up Your Flutter Project
Create a new Flutter project or use an existing one to implement the rounded bottom navigation bar.
Step 2: Define Navigation Items
Define the items that will be displayed in your rounded bottom navigation bar. These could be represented as icons, labels, or both.
List<String> listItems = ['Home', 'Gallery', 'Profile'];
List listOfIcons = [
"assets/icons/home.png",
"assets/icons/gallery.png",
"assets/icons/user.png"
];Step 3: Implement the Rounded Bottom Navigation Bar
Create a custom StatefulWidget to implement the rounded bottom navigation bar. Use the BottomNavigationBar widget with a custom shape to achieve the rounded appearance.
import 'package:flutter/material.dart';
class RoundedBottomNavigationBar extends StatelessWidget {
final int pageIdx;
final List<String> listItems;
final List listOfIcons;
final Function(int) onTap;
const RoundedBottomNavigationBar(
{super.key,
required this.pageIdx,
required this.listItems,
required this.listOfIcons,
required this.onTap});
@override
Widget build(BuildContext context) {
double displayWidth = MediaQuery.of(context).size.width;
return Container(
margin: EdgeInsets.only(
top: displayWidth * .05,
bottom: displayWidth * .08,
left: displayWidth * .13,
right: displayWidth * .13),
height: displayWidth * .155,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(.1),
blurRadius: 30,
offset: Offset(0, 10))
],
borderRadius: BorderRadius.circular(50)),
child: ListView.builder(
itemCount: 3,
scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric(horizontal: displayWidth * .02),
itemBuilder: (context, index) => InkWell(
onTap: (){
onTap(index);
},
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
child: Stack(children: [
AnimatedContainer(
duration: const Duration(seconds: 1),
curve: Curves.fastLinearToSlowEaseIn,
width: index == pageIdx
? displayWidth * .36
: displayWidth * .18,
alignment: Alignment.center,
child: AnimatedContainer(
duration: const Duration(seconds: 1),
curve: Curves.fastLinearToSlowEaseIn,
height: index == pageIdx ? displayWidth * .12 : 0,
width: index == pageIdx ? displayWidth * .32 : 0,
decoration: BoxDecoration(
color: index == pageIdx
? Colors.blueAccent.withOpacity(.2)
: Colors.transparent,
borderRadius: BorderRadius.circular(50)))),
AnimatedContainer(
duration: Duration(seconds: 1),
curve: Curves.fastLinearToSlowEaseIn,
width: index == pageIdx
? displayWidth * .31
: displayWidth * .18,
alignment: Alignment.center,
child: Stack(children: [
Row(children: [
AnimatedContainer(
duration: const Duration(seconds: 1),
curve: Curves.fastLinearToSlowEaseIn,
width: index == pageIdx ? displayWidth * .13 : 0),
AnimatedOpacity(
opacity: index == pageIdx ? 1 : 0,
duration: Duration(seconds: 1),
curve: Curves.fastLinearToSlowEaseIn,
child: Text(
index == pageIdx ? '${listItems[index]}' : '',
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 14)))
]),
Row(children: [
AnimatedContainer(
duration: Duration(seconds: 1),
curve: Curves.fastLinearToSlowEaseIn,
width:
index == pageIdx ? displayWidth * .03 : 20),
Image.asset(listOfIcons[index],
width: displayWidth * .070)
])
]))
]))));
}
}Step 4: Integrate and Customize
Integrate the RoundedBottomBarNavigation widget into your app and customize it further based on your design preferences.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_custom_bottom_navigation/navigations_bar/curved_navigation/curved_navigation_bar.dart';
import 'package:flutter_custom_bottom_navigation/navigations_bar/rounded_navigation/rounded_bottom_navigation_bar.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int pageIdx = 0;
List<String> listItems = ['Home', 'Gallery', 'Profile'];
List listOfIcons = [
"assets/icons/home.png",
"assets/icons/gallery.png",
"assets/icons/user.png"
];
setBottomBarIndex(index) {
setState(() {
pageIdx = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter bottom navigation")),
bottomNavigationBar: RoundedBottomNavigationBar(
onTap: (index) {
setState(() {
setBottomBarIndex(index);
HapticFeedback.lightImpact();
});
},
pageIdx: pageIdx,
listItems: listItems,
listOfIcons: listOfIcons),
);
}
}
Part 2: Curved Bottom Navigation Bar
Step 1: Set Up Your Flutter Project
Create a new Flutter project or use an existing one to implement the curved bottom navigation bar.
Step 2: Define Your Navigation Items
Before we dive into the custom painter, define the items that will appear in your bottom navigation bar.
import 'package:flutter/material.dart';
class NavItem {
final IconData icon;
final String title;
final Color color;
NavItem({required this.icon, required this.title, required this.color});
}
List<NavItem> navItems = [
NavItem(icon: Icons.home, title: "Home", color: Colors.teal),
NavItem(icon: Icons.search, title: "Search", color: Colors.blue),
NavItem(icon: Icons.person, title: "Profile", color: Colors.pink),
];Step 3: Implement the Curved Bottom Navigation Bar
Create a custom StatefulWidget to implement the curved bottom navigation bar. Utilize the CustomPaint widget to draw a curved shape for the navigation bar.
import 'package:flutter/material.dart';
import '../../nav_item.dart';
class CurvedNavigationBar extends StatefulWidget {
@override
_CurvedNavigationBarState createState() => _CurvedNavigationBarState();
}
class _CurvedNavigationBarState extends State<CurvedNavigationBar> {
int selectedIndex = 0;
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: CurvedNavigationBarPainter(),
child: Container(
height: kToolbarHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate(navItems.length, (index) {
NavItem currentItem = navItems[index];
return IconButton(
icon: Icon(currentItem.icon, color: selectedIndex == index ? currentItem.color : Colors.grey),
onPressed: () {
setState(() {
selectedIndex = index;
});
// Handle navigation onTap
},
);
}),
),
),
);
}
}Step 4: Create the Curved Navigation Bar Painter
Define a custom CustomPainter to draw the curved shape for the bottom navigation bar.
class CurvedNavigationBarPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
Path path = Path()..moveTo(0, 20);
path.quadraticBezierTo(size.width * 0.20, 0, size.width * 0.35, 0);
path.quadraticBezierTo(size.width * 0.40, 0, size.width * 0.40, 10);
path.arcToPoint(Offset(size.width * 0.60, 10),
radius: Radius.circular(10), clockwise: false);
path.quadraticBezierTo(size.width * 0.6, 0, size.width * 0.65, 0);
path.quadraticBezierTo(size.width * 0.8, 0, size.width, 20);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.close();
canvas.drawShadow(path, Colors.black, 5, true);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}Step 5: Integrate and Customize
Integrate the CurvedBottomBarNavigation widget into your app and customize it based on your design preferences.

Conclusion
In this article, we explored how to implement two distinct styles of bottom navigation bars in Flutter: a rounded variant and a curved variant. By customizing the BottomNavigationBar and utilizing CustomPainter, you can achieve unique and visually appealing navigation bars for your Flutter applications.
Experiment with colors, shapes, and animations to further enhance the aesthetics and user experience of your bottom navigation bars. Remember to consider usability and responsiveness while implementing custom UI components.
Happy coding!
Thank you for reading until the end. Before you go:
- Please consider clapping and following me! 👏
- Follow me on LinkedIn.
Stackademic
Thank you for reading until the end. Before you go:
- Please consider clapping and following the writer! 👏
- Follow us on Twitter(X), LinkedIn, and YouTube.
- Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.






