skip to Main Content

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


  1. Chosen as BEST ANSWER

    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 value static int currentIndex = 0; in it.

    Then replaced the variable int _selectedIndex with ApplicationData.currentIndex. Works now !


  2. There is a properties call selectedItemColor and unselectedItemColor in BottomNavigationBar in flutter.Use it with the property currentIndex.Refer the exapmle below.

     BottomNavigationBar(
      onTap: changeActiveIndex,
      currentIndex: _activeIndex,
      selectedItemColor: Colors.black,
      type: BottomNavigationBarType.fixed,
      backgroundColor: const Color(0xff251f71), // Set background color here
    
      items: ...
    )
    

    Alternatively can use unselectedItemColor and selectedItemColor as well

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search