Search code examples
flutterdartnavigation

How to add navigation in my Bottom Navigation Bar


I'm new to Flutter, I want to create a navigation bar that can change color when I tap on it. I'm done with that part. Now I'm working on how to navigate to the other page when I tap the navigation bar.

This is my code.

I don't know how to implement the navigation part in my code. I confuse with isSelected and selectedIndex. Hope someone can help me on this and clarify for my better understanding in Flutter.

class BottomNavBar extends StatefulWidget {
 
  @override
  State<BottomNavBar> createState() => _BottomNavBarState();
}

class _BottomNavBarState extends State<BottomNavBar> {

  int _isSelected = 0;


  final List<BottomNavItem> _listBottomNavItems = const [   
    BottomNavItem(title:'Home', icon: Icons.home),
    BottomNavItem(title:'Activity', icon: Icons.receipt),
    BottomNavItem(title:'Wallet', icon: Icons.credit_card),
    BottomNavItem(title:'Notification', icon: Icons.notifications),
    BottomNavItem(title:'Settings', icon: Icons.person),
  ];

  @override
  Widget build(BuildContext context) {
    return 
      
          Row(   
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: List.generate(_listBottomNavItems.length,
            (index){  
              return BottomNavItem(   
                title: _listBottomNavItems[index].title,
                icon: _listBottomNavItems[index].icon, 
                isSelected: _isSelected == index,
                onTap: (){   
                  setState((){   
                    _isSelected = index;
              
                    
                  });
                }
              );
            })
          );
     
  }
}

class BottomNavItem extends StatelessWidget {

  final String title;
  final IconData icon;
  final bool? isSelected;
  final Function()? onTap;

  const BottomNavItem({  
    required this.title,
    required this.icon,
    this.isSelected,
    this.onTap
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,  
      child: Container(  
        padding: const EdgeInsets.all(5),
        width: 50,
        height: 40,  
        decoration: BoxDecoration(  
          color: isSelected == true ? Colors.black87: Colors.transparent,
          borderRadius: BorderRadius.circular(10),
        ),

        child: Column(  
          children: [    
            Icon(icon, color: isSelected == true ? Colors.white: Colors.black87, size: 17),
            const SizedBox(height: 5,),
            Text(
              title, 
              style: TextStyle(
                fontSize: 7, 
                fontWeight: FontWeight.bold,
                color: isSelected == true ? Colors.white: Colors.black87
              ),
            )
          ],
        )
      ) 
    );
  }
}

Solution

  • You can add the page in BottomNavItem like this

    class BottomNavItem extends StatelessWidget {
          
            final String title;
            final IconData icon;
            final bool? isSelected;
            final Function()? onTap;
            final Widget page;
          
            const BottomNavItem({
              required this.title,
              required this.icon,
              required this.page,
              this.isSelected,
              this.onTap
            });
          
            @override
            Widget build(BuildContext context) {
              return GestureDetector(
                  onTap: () {
                    onTap!();
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(
                        builder: (context) => page,
                      ),
                    );
                  },
                  child: Container(
                      padding: const EdgeInsets.all(5),
                      width: 50,
                      height: 40,
                      decoration: BoxDecoration(
                        color: isSelected == true ? Colors.black87: Colors.transparent,
                        borderRadius: BorderRadius.circular(10),
                      ),
          
                      child: Column(
                        children: [
                          Icon(icon, color: isSelected == true ? Colors.white: Colors.black87, size: 17),
                          const SizedBox(height: 5,),
                          Text(
                            title,
                            style: TextStyle(
                                fontSize: 7,
                                fontWeight: FontWeight.bold,
                                color: isSelected == true ? Colors.white: Colors.black87
                            ),
                          )
                        ],
                      )
                  )
              );
            }
          }
    

    then just add your page in list.

    final List<BottomNavItem> _listBottomNavItems = const [   
      BottomNavItem(title:'Home', icon: Icons.home, page: Home()),
      BottomNavItem(title:'Activity', icon: Icons.receipt, page: Activity()),
      BottomNavItem(title:'Wallet', icon: Icons.credit_card, page: Wallet()),
      BottomNavItem(title:'Notification', icon: Icons.notifications, page: Notification()),
      BottomNavItem(title:'Settings', icon: Icons.person, page: Settings()),
    ];