skip to Main Content

I am trying to implement a bottomNavigationBar that goes to different pages. So far, I have made the bulk of everything, which you can see in my code below.

Here is my bottomNavigationBar code in navBar.dart:

// ignore: file_names
import 'package:bottom_navy_bar/bottom_navy_bar.dart';
import 'package:flutter/material.dart';

import '../views/home_page.dart';
import '../views/secondScreen.dart';

// ignore: camel_case_types
class navBar extends StatefulWidget {
  const navBar({Key? key}) : super(key: key);

  @override
  State<navBar> createState() => _navBarState();
}

// ignore: camel_case_types
class _navBarState extends State<navBar> {
  int currentIndex = 0;
  final screens = [
    const HomePage(),
    const SecondRoute(),
    const SecondRoute(),
    const SecondRoute(),
  ];

  @override
  Widget build(BuildContext context) {
    screens[currentIndex];
    return BottomNavyBar(
      animationDuration: const Duration(milliseconds: 260),
      curve: Curves.ease,
      showElevation: false,
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      selectedIndex: currentIndex,
      onItemSelected: (index) {
        setState(() {
          currentIndex = index;
        });
        // Push the new page onto the navigation stack
        // Navigator.push(
        //   context,
        //   MaterialPageRoute(builder: (context) => pages[index]),
        // );
      },
      items: <BottomNavyBarItem>[
        BottomNavyBarItem(
          inactiveColor: const Color.fromARGB(255, 20, 143, 199),
          activeColor: const Color.fromARGB(255, 5, 176, 255),
          textAlign: TextAlign.center,
          icon: const Icon(Icons.home),
          title: const Text('Home'),
        ),
        BottomNavyBarItem(
          inactiveColor: const Color.fromARGB(255, 20, 143, 199),
          activeColor: const Color.fromARGB(255, 5, 176, 255),
          textAlign: TextAlign.center,
          icon: const Icon(Icons.discord),
          title: const Text('Discord'),
        ),
        BottomNavyBarItem(
          inactiveColor: const Color.fromARGB(255, 20, 143, 199),
          activeColor: const Color.fromARGB(255, 5, 176, 255),
          textAlign: TextAlign.center,
          icon: const Icon(Icons.school),
          title: const Text('Examotron'),
        ),
        BottomNavyBarItem(
          inactiveColor: const Color.fromARGB(255, 20, 143, 199),
          activeColor: const Color.fromARGB(255, 5, 176, 255),
          textAlign: TextAlign.center,
          icon: const Icon(Icons.document_scanner),
          title: const Text('Notes'),
        ),
      ],
    );
  }
}

And here is my home page home_page.dart:

import 'package:xconcordia/services/remote_service.dart';
import 'package:flutter/material.dart';
import 'package:xconcordia/views/secondScreen.dart';
import 'package:xconcordia/widgets/categoryPicker.dart';
import '../widgets/libraryCards.dart';
import '../widgets/libraryStatsHeader.dart';
import '../widgets/navBar.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

var webb = '';
String webOccupancy = '';
String greyOccupancy = '';
String vannierOccupancy = '';
String libTime = '';
String webLevel = '';
String greyLevel = '';
String vannierLevel = '';

class _HomePageState extends State<HomePage> {
  bool isLoading = false;
  int currentIndex = 1;

  // List of pages
  List<Widget> pages = [
    const HomePage(),
    const SecondRoute(),
    const SecondRoute(),
    const SecondRoute(),
  ];
  @override
  void initState() {
    super.initState();
    _fetchWebOccupancy();
    _fetchVannierOccupancy();
    _fetchGreyOccupancy();
    _fetchLibTime();
  }

  Future<void> _fetchLibTime() async {
    if (libTime == '') {
      String? libraryTime = await getDataAPI_time().getPosts();
      setState(() {
        libTime = libraryTime.toString();
      });
    }
  }

  Future<void> _fetchWebOccupancy() async {
    if (webOccupancy == '') {
      String? occupancy = await getDataAPI().getPosts();
      setState(() {
        webOccupancy = occupancy!.substring(0, occupancy.length - 5);
        if (webOccupancy == '' || int.parse(webOccupancy) < 0) {
          webOccupancy = '0';
        }
        if (int.parse(webOccupancy) > 100) {
          webLevel = 'High';
        } else if (int.parse(webOccupancy) > 75 &&
            int.parse(webOccupancy) < 100) {
          webLevel = 'Medium';
        } else {
          webLevel = 'Low';
        }
        isLoading = false;
      });
    }
  }

  Future<void> _fetchGreyOccupancy() async {
    if (greyOccupancy == '') {
      String? occupancy = await getDataAPI_G().getPosts();
      setState(() {
        greyOccupancy = occupancy!.substring(0, occupancy.length - 5);
        if (greyOccupancy == '' || int.parse(greyOccupancy) < 0) {
          greyOccupancy = '0';
        }
        if (int.parse(greyOccupancy) > 100) {
          greyLevel = 'High';
        } else if (int.parse(greyOccupancy) > 50 &&
            int.parse(greyOccupancy) < 100) {
          greyLevel = 'Medium';
        } else {
          greyLevel = 'Low';
        }
        isLoading = false;
      });
    }
  }

  Future<void> _fetchVannierOccupancy() async {
    if (vannierOccupancy == '') {
      String? occupancy = await getDataAPI_V().getPosts();
      setState(() {
        vannierOccupancy = occupancy!.substring(0, occupancy.length - 5);
        if (vannierOccupancy == '' || int.parse(vannierOccupancy) < 0) {
          vannierOccupancy = '0';
        }
        if (int.parse(vannierOccupancy) > 100) {
          vannierLevel = 'High';
        } else if (int.parse(vannierOccupancy) > 50 &&
            int.parse(vannierOccupancy) < 100) {
          vannierLevel = 'Medium';
        } else {
          vannierLevel = 'Low';
        }
        isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        // elevation: 15,
        // leading: IconButton(
        //   icon: const Icon(Icons.menu),
        //   onPressed: () {},
        // ),

        title: const Text('xConcordia'),
        flexibleSpace: Container(
          decoration: const BoxDecoration(
            boxShadow: [
              BoxShadow(
                color: Color.fromARGB(223, 57, 25, 163),
                offset: Offset(0, 0),
                blurRadius: 20,
              ),
            ],
            gradient: LinearGradient(
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
              colors: [Colors.blue, Colors.purple],
            ),
          ),
        ),
      ),
      body: isLoading
          ? const Center(
              child: LinearProgressIndicator(
              color: Color.fromARGB(162, 114, 68, 251),
            ))
          : Container(
              margin: const EdgeInsets.only(top: 20),
              child: Column(
                children: [
                  // ignore: prefer_const_constructors
                  LibraryStatsHeader(), //LibraryStatsHeader widget is in a file called libraryStatsHeader
                  const Padding(padding: EdgeInsets.all(10)),
                  libCards(), //libCards widget is in a file called libraryCards
                  const categoryPicker(), //category picker
                ],
              ),
            ),
      bottomNavigationBar: const navBar(),
    );
  }
}

The issue in the above code is, despite my nav bar working (as in, clicking it changes the nav bar icons), the page state does not change (i.e, it doesn’t go to another page, stays on the current page)

Now, I realize that I’m not doing anything with my screens [] array, so I should use that, and so in my navBar.dart, I thought to return body: screens[currentIndex] to make this logic work, so my nav bar is functional.

So, in this navBar.dart file, I surrounded the return with a Scaffold and did just that:

  Widget build(BuildContext context) {
      return Scaffold(
      body: screens[currentIndex],
      bottomNavigationBar: BottomNavyBar(
        animationDuration: const Duration(milliseconds: 250),
        curve: Curves.ease,
        showElevation: false,
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        selectedIndex: currentIndex,
        onItemSelected: (index) {
          setState(() {
            currentIndex = index;
          });
          // Push the new page onto the navigation stack
          // Navigator.push(
          //   context,
          //   MaterialPageRoute(builder: (context) => pages[index]),
          // );
        },
        items: <BottomNavyBarItem>[
          BottomNavyBarItem(
            inactiveColor: const Color.fromARGB(255, 20, 143, 199),
            activeColor: const Color.fromARGB(255, 5, 176, 255),
            textAlign: TextAlign.center,
            icon: const Icon(Icons.home),
            title: const Text('Home'),
          ),
          BottomNavyBarItem(
            inactiveColor: const Color.fromARGB(255, 20, 143, 199),
            activeColor: const Color.fromARGB(255, 5, 176, 255),
            textAlign: TextAlign.center,
            icon: const Icon(Icons.discord),
            title: const Text('Discord'),
          ),
          BottomNavyBarItem(
            inactiveColor: const Color.fromARGB(255, 20, 143, 199),
            activeColor: const Color.fromARGB(255, 5, 176, 255),
            textAlign: TextAlign.center,
            icon: const Icon(Icons.school),
            title: const Text('Examotron'),
          ),
          BottomNavyBarItem(
            inactiveColor: const Color.fromARGB(255, 20, 143, 199),
            activeColor: const Color.fromARGB(255, 5, 176, 255),
            textAlign: TextAlign.center,
            icon: const Icon(Icons.document_scanner),
            title: const Text('Notes'),
          ),
        ],
      ),
    );
  }

Doing this, I get an infinite loop of the same error:

Error

What is flawed in my logic when I try to return the Scaffold with the screens[currentIndex] as the body? Is it wrong? How else would I get this navigation bar working?

EDIT: I have added nav bar to my main.dart file, replacing home: HomePage() with navBar():

import 'package:flutter/material.dart';
import '../widgets/navBar.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: navBar(),
    );
  }
}

Yet, I still get the same error.

2

Answers


  1. Try this in Scaffold

    return Scaffold(
      body: screens.elementAt(currentIndex),
      bottomNavigationBar: BottomNavyBar(
    

    Remove bottomNavigationBar: const navBar() from homepage

    Call navBar class in home of main.dart file as below

    void main() {
    runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
     const MyApp({super.key});
    
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      home: navBar(), <------ here
     );
    }
    }
    
    Login or Signup to reply.
  2. In your homePage(), remove list of pages, currentIndex and bottom navBar.
    Your homePage() should look like this:

    import 'package:flutter/material.dart';
    
    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    var webb = '';
    String webOccupancy = '';
    String greyOccupancy = '';
    String vannierOccupancy = '';
    String libTime = '';
    String webLevel = '';
    String greyLevel = '';
    String vannierLevel = '';
    
    class _HomePageState extends State<HomePage> {
      bool isLoading = true;
      @override
      void initState() {
        super.initState();
        _fetchWebOccupancy();
        _fetchVannierOccupancy();
        _fetchGreyOccupancy();
        _fetchLibTime();
      }
    
      Future<void> _fetchLibTime() async {
        if (libTime == '') {
          String? libraryTime = await getDataAPI_time().getPosts();
          setState(() {
            libTime = libraryTime.toString();
          });
        }
      }
    
      Future<void> _fetchWebOccupancy() async {
        if (webOccupancy == '') {
          String? occupancy = await getDataAPI().getPosts();
          setState(() {
            webOccupancy = occupancy!.substring(0, occupancy.length - 5);
            if (webOccupancy == '' || int.parse(webOccupancy) < 0) {
              webOccupancy = '0';
            }
            if (int.parse(webOccupancy) > 100) {
              webLevel = 'High';
            } else if (int.parse(webOccupancy) > 75 &&
                int.parse(webOccupancy) < 100) {
              webLevel = 'Medium';
            } else {
              webLevel = 'Low';
            }
            isLoading = false;
          });
        }
      }
    
      Future<void> _fetchGreyOccupancy() async {
        if (greyOccupancy == '') {
          String? occupancy = await getDataAPI_G().getPosts();
          setState(() {
            greyOccupancy = occupancy!.substring(0, occupancy.length - 5);
            if (greyOccupancy == '' || int.parse(greyOccupancy) < 0) {
              greyOccupancy = '0';
            }
            if (int.parse(greyOccupancy) > 100) {
              greyLevel = 'High';
            } else if (int.parse(greyOccupancy) > 50 &&
                int.parse(greyOccupancy) < 100) {
              greyLevel = 'Medium';
            } else {
              greyLevel = 'Low';
            }
            isLoading = false;
          });
        }
      }
    
      Future<void> _fetchVannierOccupancy() async {
        if (vannierOccupancy == '') {
          String? occupancy = await getDataAPI_V().getPosts();
          setState(() {
            vannierOccupancy = occupancy!.substring(0, occupancy.length - 5);
            if (vannierOccupancy == '' || int.parse(vannierOccupancy) < 0) {
              vannierOccupancy = '0';
            }
            if (int.parse(vannierOccupancy) > 100) {
              vannierLevel = 'High';
            } else if (int.parse(vannierOccupancy) > 50 &&
                int.parse(vannierOccupancy) < 100) {
              vannierLevel = 'Medium';
            } else {
              vannierLevel = 'Low';
            }
            isLoading = false;
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.transparent,
            // elevation: 15,
            // leading: IconButton(
            //   icon: const Icon(Icons.menu),
            //   onPressed: () {},
            // ),
    
            title: const Text('xConcordia'),
            flexibleSpace: Container(
              decoration: const BoxDecoration(
                boxShadow: [
                  BoxShadow(
                    color: Color.fromARGB(223, 57, 25, 163),
                    offset: Offset(0, 0),
                    blurRadius: 20,
                  ),
                ],
                gradient: LinearGradient(
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                  colors: [Colors.blue, Colors.purple],
                ),
              ),
            ),
          ),
          body: isLoading
              ? const Center(
              child: LinearProgressIndicator(
                color: Color.fromARGB(162, 114, 68, 251),
              ))
              : Container(
            margin: const EdgeInsets.only(top: 20),
            child: Column(
              children: [
                // ignore: prefer_const_constructors
                LibraryStatsHeader(), //LibraryStatsHeader widget is in a file called libraryStatsHeader
                const Padding(padding: EdgeInsets.all(10)),
                libCards(), //libCards widget is in a file called libraryCards
                const categoryPicker(), //category picker
                
              ],
            ),
          ),
          
        );
      }
    }
    

    Do not add bottomNavigation to the list of pages like homePage(), secondRoute(), etc.

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