Flutter Animated Bottom Navigation Bar

This article explains you how to create flutter animated bottom navigation bar without using any third party package or library. You can also check flutter navigation related articles.

In this flutter example, we are creating custom bottom navigation bar with animation for android & iOS platforms. Whenever user clicks on tab in bottom bar, tab will be animated and expanded. We can customize this tabs texts and icons according to our requirement.

Bottom Navigation Bar widget has many properties. backgroundColor property is used to set background color of custom bottom navigation bar. selectedIndex property is used to set position of selected item so we can animate that item. onItemSelected callback is used when bottom navigation bar tab is pressed.

itemCornerRadius attribute is used to set corner radius of navigation bar item. We can also display elevation around bottom navigation bar with showElevation property. curve property is used to configure animation curve. items property is used to display number of tabs in bottom bar. We can set minimum 2 and maximum 5 tabs in this custom bottom bar.

 

Main Body UI for Bottom Navigation Bar

int currentPosition = 0;
Color inactiveColor = Colors.grey;

Widget mainBodyWidget() {
List<Widget> pages = [
Container(
alignment: Alignment.center,
child: Text(
    “USERS”,
    style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
),
Container(
alignment: Alignment.center,
child: Text(
    “LOCATION”,
    style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
),
Container(
alignment: Alignment.center,
child: Text(
    “MESSAGES”,
    style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
),
Container(
alignment: Alignment.center,
child: Text(
    “SETTINGS”,
    style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
),
];
return IndexedStack(
    children: pages,
    index: currentPosition,
);
}

 
 

Create Modal Class for Custom Bottom Navigation Bar

import ‘package:flutter/material.dart’;

class MyBottomNavigationBarItem {

final Widget title;
final Widget icon;
final TextAlign textAlign;
final Color activeColor;
final Color inactiveColor;

MyBottomNavigationBarItem({
    @required this.title,
    @required this.icon,
    this.textAlign,
    this.activeColor,
    this.inactiveColor,
});

}

 
 

Customize Flutter Animated Bottom Navigation Bar Item

import ‘package:flutter/material.dart’;
import ‘my_bottom_navigation_bar_item.dart’;

class MyBottomNavigationBarItemWidget extends StatelessWidget {
final bool isSelected;
final double iconSize;
final Color backgroundColor;
final Duration animationDuration;
final double itemCornerRadius;
final MyBottomNavigationBarItem item;
final Curve curve;

const MyBottomNavigationBarItemWidget({
    Key key,
    @required this.isSelected,
    @required this.iconSize,
    @required this.backgroundColor,
    @required this.animationDuration,
    @required this.itemCornerRadius,
    @required this.item,
    this.curve = Curves.linear,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return Semantics(
selected: isSelected,
container: true,
child: AnimatedContainer(
duration: animationDuration,
curve: curve,
width: isSelected ? 120 : 60,
height: double.maxFinite,
decoration: BoxDecoration(
color: isSelected ? item.activeColor.withOpacity(0.2) : backgroundColor,
borderRadius: BorderRadius.circular(itemCornerRadius),
),
child: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
width: isSelected ? 120 : 60,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
IconTheme(
data: IconThemeData(
size: iconSize,
color: isSelected
? item.activeColor.withOpacity(1)
: item.inactiveColor == null
? item.activeColor
: item.inactiveColor,
),
child: item.icon,
),
if (isSelected)
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 4),
child: DefaultTextStyle.merge(
child: item.title,
textAlign: item.textAlign,
style: TextStyle(
color: item.activeColor,
fontWeight: FontWeight.bold,
),
maxLines: 1,
),
),
),
],
),
),
),
),
);
}
}

 
 

Flutter Custom Bottom Navigation Bar

import ‘package:flutter/material.dart’;
import ‘package:flutteranimatedbottombar/my_bottom_navigation_bar_item.dart’;
import ‘package:flutteranimatedbottombar/my_bottom_navigation_bar_item_widget.dart’;

class MyBottomNavigationBar extends StatelessWidget {

MyBottomNavigationBar({
    Key key,
    this.containerHeight = 56,
    this.itemCornerRadius = 50,
    this.curve = Curves.linear,
    this.bgColor,
    this.showElevation = true,
    this.selectedPosition = 0,
    @required this.onItemSelected,
    @required this.items,
    this.iconSize = 24,
    this.animationDuration = const Duration(milliseconds: 270),
    this.mainAxisAlignment = MainAxisAlignment.spaceBetween,

}) : assert(items.length >= 2 && items.length <= 5),
super(key: key);

final List<MyBottomNavigationBarItem> items;
final int selectedPosition;
final Duration animationDuration;
final bool showElevation;
final double iconSize;
final Color bgColor;
final Curve curve;
final double itemCornerRadius;
final double containerHeight;
final MainAxisAlignment mainAxisAlignment;
final ValueChanged<int> onItemSelected;

@override
Widget build(BuildContext context) {
final backgroundColor = bgColor ?? Theme.of(context).bottomAppBarColor;

return Container(
decoration: BoxDecoration(
color: backgroundColor,
boxShadow: [
if (showElevation)
const BoxShadow(
color: Colors.black12,
blurRadius: 2,
),
],
),
child: SafeArea(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10),
width: double.infinity,
height: containerHeight,
child: Row(
mainAxisAlignment: mainAxisAlignment,
children: items.map((item) {
var index = items.indexOf(item);
return GestureDetector(
onTap: () => onItemSelected(index),
child: MyBottomNavigationBarItemWidget(
iconSize: iconSize,
isSelected: index == selectedPosition,
backgroundColor: backgroundColor,
animationDuration: animationDuration,
item: item,
itemCornerRadius: itemCornerRadius,
curve: curve,
),
);
}).toList(),
),
),
),
);
}
}

 
 

Integrate Flutter Animated Bottom Navigation Bar

Widget bottomNavigationBarWidget() {
return MyBottomNavigationBar(
containerHeight: 75,
itemCornerRadius: 25,
curve: Curves.easeIn,
bgColor: Colors.black,
showElevation: true,
selectedPosition: currentPosition,
onItemSelected: (index) => setState(() => currentPosition = index),
items: <MyBottomNavigationBarItem>[
MyBottomNavigationBarItem(
    icon: Icon(Icons.people),
    title: Text(‘Users’),
    activeColor: Colors.orangeAccent,
    inactiveColor: inactiveColor,
    textAlign: TextAlign.center,
),
MyBottomNavigationBarItem(
    icon: Icon(Icons.location_on),
    title: Text(‘Location’),
    activeColor: Colors.pinkAccent,
    inactiveColor: inactiveColor,
    textAlign: TextAlign.center,
),
MyBottomNavigationBarItem(
    icon: Icon(Icons.message),
    title: Text(‘Messages ‘),
    activeColor: Colors.tealAccent,
    inactiveColor: inactiveColor,
    textAlign: TextAlign.center,
),
MyBottomNavigationBarItem(
    icon: Icon(Icons.settings),
    title: Text(‘Settings’),
    activeColor: Colors.deepOrangeAccent,
    inactiveColor: inactiveColor,
    textAlign: TextAlign.center,
),
],
);
}
 
@override
Widget build(BuildContext context) {
return Scaffold(
    appBar: AppBar(title: Text(‘Flutter Bottom Navigation Bar Sample’)),
    body: mainBodyWidget(),
    bottomNavigationBar: bottomNavigationBarWidget());
}
 
 
 
flutter animated bottom navigation bar
 
 
flutter animated bottom navigation bar