skip to Main Content

I am trying to add a side menu and a bottom navigation bar to my flutter app. I have combined the code into the main_screen.dart file.

When I run the code, the bottom navigation bar works fine but if I tap on a side menu item I get this error:

_AssertionError (‘package:flutter/src/material/bottom_navigation_bar.dart’: Failed assertion: line 251 pos 15: ‘0 <= currentIndex && currentIndex < items.length’: is not true.)

Here is the main_screen.dart code:

 class MainScreenState extends State<MainScreen> {
  final auth = FirebaseAuth.instance;
  int _pageIndex = 0;

  final List<Widget> appScreens = [
    const CompanyDashboardScreen(),
    const TransactionDetailScreen(true),
    const AppointmentCalendarScreen(),
    const UserProfileScreen(),
    const ChatScreen(),
    const CompanyScreen(),
    const UserProfileScreen(),
  ];

  Future<void> signOut() async {
    await auth.signOut();
  }

  void onItemTapped(int index) {
    setState(() {
      _pageIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(),
      body: Container(child: appScreens[_pageIndex]),
      drawer: Drawer(
        child: (ListView(
          padding: EdgeInsets.zero,
          children: [
            const UserAccountsDrawerHeader(
              accountName: Text('Billy Bob Baker'),
              accountEmail: Text('[email protected]'),
            ),
            Container(
              child: Column(
                children: <Widget>[
                  ListTile(
                    title: const Text('Add Company'),
                    selected: _pageIndex == 5,
                    onTap: () {
                      // Update the state of the app
                      onItemTapped(5);
                      // Then close the drawer
                      Navigator.pop(context);
                    },
                  ),
                  ListTile(
                    title: const Text('Add User'),
                    selected: _pageIndex == 6,
                    onTap: () {
                      // Update the state of the app
                      onItemTapped(6);
                      // Then close the drawer
                      Navigator.pop(context);
                    },
                  ),
                  ListTile(
                    title: const Text('Log Out'),
                    selected: _pageIndex == 7,
                    onTap: () {
                      // Update the state of the app
                      signOut();
                      // Then close the drawer
                      Navigator.pop(context);
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const LoginScreen()));
                    },
                  ),
                ],
              ),
            ),
          ],
        )),
      ),
      bottomNavigationBar: BottomNavigationBar(  <<<  ERROR HERE
        backgroundColor: Colors.blueAccent,
        selectedIconTheme: const IconThemeData(color: Colors.white),
        selectedItemColor: Colors.white,
        unselectedItemColor: Colors.black45,
        type: BottomNavigationBarType.fixed,
        currentIndex: _pageIndex,
        onTap: (value) {
          setState(() {
            _pageIndex = value;
          });
        },
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
          BottomNavigationBarItem(
              icon: Icon(Icons.add_business_outlined), label: "Trxn"),
          BottomNavigationBarItem(
              icon: Icon(Icons.calendar_today), label: "Calendar"),
          BottomNavigationBarItem(icon: Icon(Icons.people), label: "User"),
          BottomNavigationBarItem(icon: Icon(Icons.chat), label: 'Chat'),
        ],
      ),
    );
  }

  // Added this for BottomNavigationBar sync
  void setIndex(int index) {
    if (mounted) setState(() => _pageIndex = index);
  }
}

How do I combine the 2 navigation methods without having them interfere with each other?

Thanks

2

Answers


  1. The ListTiles in your drawer can set the _pageIndex to 5, 6, and 7 but there are only 5 items in your BottomNavigationBar (max valid index is 4).

    I would suggest separating the logic of the drawer ListTiles from the BottomNavigationBar. In other words, don’t let the drawer update the page index. Instead, tapping on a tile in the drawer should navigate to a new page.

    You can reference this page to learn how navigation works in Flutter: https://docs.flutter.dev/cookbook/navigation/navigation-basics

    ListTile(
                        title: const Text('Add User'),
                        onTap: () {
                          // Close the drawer
                          Navigator.pop(context);
                          // Navigate to new page
                          Navigator.push(
                            context,
                            MaterialPageRoute(builder: (context) => 
                            const SecondRoute()),
                           );
                        },
                      ),
    
    Login or Signup to reply.
  2. For combining a side menu and a bottom navigation bar, a Scaffold with a Drawer for the side menu and a BottomNavigationBar for the bottom navigation bar should be used. The structure for the build method:

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: CustomAppBar(),
        drawer: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: [
              UserAccountsDrawerHeader(
                accountName: Text('Billy Bob Baker'),
                accountEmail: Text('[email protected]'),
              ),
              ListTile(
                title: Text('Add Company'),
                selected: _pageIndex == 5,
                onTap: () {
                  onItemTapped(5);
                  Navigator.pop(context);
                },
              ),
              ListTile(
                title: Text('Add User'),
                selected: _pageIndex == 6,
                onTap: () {
                  onItemTapped(6);
                  Navigator.pop(context);
                },
              ),
              ListTile(
                title: Text('Log Out'),
                selected: _pageIndex == 7,
                onTap: () {
                  signOut();
                  Navigator.pop(context);
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => LoginScreen()),
                  );
                },
              ),
            ],
          ),
        ),
        body: Container(child: appScreens[_pageIndex]),
        bottomNavigationBar: BottomNavigationBar(
          backgroundColor: Colors.blueAccent,
          selectedIconTheme: IconThemeData(color: Colors.white),
          selectedItemColor: Colors.white,
          unselectedItemColor: Colors.black45,
          type: BottomNavigationBarType.fixed,
          currentIndex: _pageIndex,
          onTap: (value) {
            setState(() {
              _pageIndex = value;
            });
          },
          items: const [
            BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
            BottomNavigationBarItem(
                icon: Icon(Icons.add_business_outlined), label: "Trxn"),
            BottomNavigationBarItem(
                icon: Icon(Icons.calendar_today), label: "Calendar"),
            BottomNavigationBarItem(icon: Icon(Icons.people), label: "User"),
            BottomNavigationBarItem(icon: Icon(Icons.chat), label: 'Chat'),
          ],
        ),
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search