In my flutter app, I have created CustomBottomTabBar to be used as a reusable widget in all pages. Just 4 icons to navigate to different pages and change color upon selection.
class CustomBottomTabBar extends StatefulWidget {
const CustomBottomTabBar({super.key});
@override
_CustomBottomTabBarState createState() => _CustomBottomTabBarState();
}
class _CustomBottomTabBarState extends State<CustomBottomTabBar> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
// Navigate to different pages based on the index
......Navigation code.....
}
@override
Widget build(BuildContext context) {
return Container(
width: 375.0,
height: 89.0,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
decoration: const BoxDecoration(
color: Color(0xFF272F3E),
boxShadow: [
BoxShadow(
color: Color(0x14000000),
offset: Offset(0, -1),
blurRadius: 8.0,
),
],
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32.0),
topRight: Radius.circular(32.0),
),
),
child: Stack(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildNavItem(0, 'Home', 'assets/images/HouseIcon.png'),
_buildNavItem(1, 'Appointments', 'assets/images/AppointmentIcon.png'),
_buildNavItem(2, 'Chat', 'assets/images/ChatIcon.png'),
_buildNavItem(3, 'Profile', 'assets/images/UserIcon.png'),
],
),
Positioned(
top: 63.0,
left: 0,
child: Container(
width: 375.0,
height: 26.0,
padding: const EdgeInsets.fromLTRB(119.0, 13.0, 117.0, 8.0),
child: Container(
width: 139.0,
height: 5.0,
decoration: const BoxDecoration(
color: Color(0xFFF8FAFC),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(100.0),
topRight: Radius.circular(100.0),
),
),
),
),
),
],
),
);
}
Widget _buildNavItem(int index, String label, String iconPath) {
bool isSelected = _selectedIndex == index;
Color color = isSelected ? const Color(0xFF06B6D4) : Colors.white;
setState(() {
color = isSelected ? const Color(0xFF06B6D4) : Colors.white;
});
print("index is $index and selectedIndex is $_selectedIndex color is $color");
return GestureDetector(
onTap: () => _onItemTapped(index),
child: SizedBox(
width: 85.75,
height: 63.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 24.0,
height: 24.0,
padding: const EdgeInsets.fromLTRB(3.0, 0.75, 1.5, 3.75),
child: Image.asset(
iconPath,
width: 18.0,
height: 18.75,
color: color,
),
),
const SizedBox(height: 10.0),
Text(
label,
style: TextStyle(
fontFamily: 'Plus Jakarta Sans',
fontSize: 12.0,
fontWeight: FontWeight.bold,
height: 1.33,
letterSpacing: -0.02,
color: color,
),
),
],
),
),
);
}
}
While page navigation works perfect, the icons just don’t change color, its always 1st icon as selected color, rest all white.
When I try to print print("index is $index and selectedIndex is $_selectedIndex color is $color");
and if I selected 4th icon, I get correct results in print and logic too
I/flutter (10685): index is 3 and selectedIndex is 0 color is Color(0xffffffff)
I/flutter (10685): index is 0 and selectedIndex is 3 color is Color(0xffffffff)
I/flutter (10685): index is 1 and selectedIndex is 3 color is Color(0xffffffff)
I/flutter (10685): index is 2 and selectedIndex is 3 color is Color(0xffffffff)
I/flutter (10685): index is 3 and selectedIndex is 3 color is Color(0xff06b6d4) //4th should be this color
But in actual it just flickers for a second and back to 1st icon being selected color and rest all remain white.
I am calling widget like this in target page
bottomNavigationBar: const CustomBottomTabBar(),
Tried various answers here like returning BottomNavigationBar
instead of Container
the result is same.
What am I missing here ?
2
Answers
Got it finally !
Logic was ok, The tab bar state was not carried across pages. So created a file
ApplicationData.dart
and create a static valuestatic int currentIndex = 0;
in it.Then replaced the variable
int _selectedIndex
withApplicationData.currentIndex
. Works now !There is a properties call selectedItemColor and unselectedItemColor in BottomNavigationBar in flutter.Use it with the property currentIndex.Refer the exapmle below.
Alternatively can use unselectedItemColor and selectedItemColor as well