BottomNavigatorBar disappears after navigating to another page, GoRouter

46 Views Asked by At

So I want to use GoRouter to navigate from page to page, because I am developing a website using flutter and I want the URL to change as I navigate from one page to another. However I encountered an issue since I want to use Tabs. I decided to use BottomNavigatorBar because I knew about it, but when I navigate to any other page than the first (default) page after log in, the whole BottomNavigationBar disappears. I don't know why. This is my code for the HomePage.

class HomePage extends StatefulWidget {

  HomePage({Key? key}) : super(key: key);

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

class _HomePageState extends State<HomePage> {
  List<Recipe> recipes = [];
  bool dataFetched = false;
  User? user;
  PageController _pageController = PageController();

  int _selectedIndex = 0;

  final List<String> _routeNames = [
    MyAppRouteConstants.profileRouteName,
    MyAppRouteConstants.addRecipeRouteName,
    MyAppRouteConstants.publicRecipeRouteName,
    MyAppRouteConstants.favoritesRouteName
  ];

  String? getToken() {
    return html.window.localStorage['token'];
  }

  @override
  void initState() {
    super.initState();
    fetchAndSetUser();
    fetchAndSetRecipes();
  }

  void fetchAndSetUser() async{
    String? token = getToken();

    user = await fetchUserData(token!);
  }

  Future<void> fetchAndSetRecipes() async {
    try {
      String? token = getToken();
      if (token != null) {
        List<Map<String, dynamic>> fetchedRecipeData = await fetchRecipeData(token);

        List<Recipe> fetchedRecipes = [];
        for (Map<String, dynamic> recipeMap in fetchedRecipeData) {
          Recipe recipe = Recipe.fromJson(recipeMap);
          fetchedRecipes.add(recipe);
        }
        setState(() {
          recipes = fetchedRecipes;
          dataFetched = true;
        });
      } else {
        print('Token is missing. Please log in.');
      }
    } catch (e) {
      print('Error fetching recipes: $e');
    }
  }

  Future<void> refreshRecipes() async {
    await fetchAndSetRecipes();
  }

  Widget _buildPage(int index) {
    switch (index) {
      case 0:
        return ProfilePage();
      case 1:
        return CreateActivityPage();
      case 2:
        return PublicRecipePage();
      case 3:
        return FavoritesPage();
      default:
        return UnknownPage();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: _pageController,
        children: [
          ProfilePage(),
          CreateActivityPage(),
          PublicRecipePage(),
          FavoritesPage(),
        ],
        onPageChanged: (index) {
          setState(() {
            _selectedIndex = index;
          });
          _updateUrl(index);
        },
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: (index) {
          setState(() {
            _selectedIndex = index;
          });
          _pageController.animateToPage(
            index,
            duration: Duration(milliseconds: 500),
            curve: Curves.ease,
          );
          _updateUrl(index);
        },
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
          BottomNavigationBarItem(icon: Icon(Icons.add), label: 'Add Recipe'),
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Public Recipes'),
          BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Favorites'),
        ],
      ),
    );
  }

  void _updateUrl(int index) {
    final routeName = _routeNames[index];
    GoRouter.of(context).goNamed(routeName);
  }
}

My GoRouter looks like this

class MyAppRouter{

  GoRouter router = GoRouter(

    routes: [
      GoRoute(
          name: MyAppRouteConstants.defaultRouteName,
          path: '/',
          pageBuilder: (context, state){
            return MaterialPage(child: UnknownPage());
          }
      ),
      GoRoute(
        name: MyAppRouteConstants.registerRouteName,
        path: '/register',
        pageBuilder: (context, state){
          return MaterialPage(child: RegisterPage());
        }
      ),
      GoRoute(
          name: MyAppRouteConstants.loginRouteName,
          path: '/login',
          pageBuilder: (context, state){
            return MaterialPage(child: LogInPage());
          }
      ),
      GoRoute(
          name: MyAppRouteConstants.profileRouteName,
          path: '/profile_page',
          pageBuilder: (context, state){
            return MaterialPage(child: HomePage());
          }
      ),
      GoRoute(
          name: MyAppRouteConstants.addRecipeRouteName,
          path: '/add_recipe',
          pageBuilder: (context, state){
            return MaterialPage(child: CreateActivityPage());
          }
      ),
      GoRoute(
          name: MyAppRouteConstants.publicRecipeRouteName,
          path: '/public_recipes',
          pageBuilder: (context, state){
            return MaterialPage(child: PublicRecipePage());
          }
      ),
      GoRoute(
          name: MyAppRouteConstants.favoritesRouteName,
          path: '/favorites',
          pageBuilder: (context, state){
            return MaterialPage(child: FavoritesPage());
          }
      ),
    ],
    errorPageBuilder: (context, state){
      return MaterialPage(child: UnknownPage());
    }

  );
}

class MyAppRouteConstants{
  static const String defaultRouteName = 'default';
  static const String registerRouteName = 'register';
  static const String loginRouteName = 'login';
  static const String profileRouteName = 'profile_page';
  static const String addRecipeRouteName = 'add_recipe';
  static const String publicRecipeRouteName = 'public_recipes';
  static const String favoritesRouteName = 'favorites';

  static final Map<String, GlobalKey<NavigatorState>> tabNavigatorKeys = {
    profileRouteName: GlobalKey<NavigatorState>(),
    addRecipeRouteName: GlobalKey<NavigatorState>(),
    publicRecipeRouteName: GlobalKey<NavigatorState>(),
    favoritesRouteName: GlobalKey<NavigatorState>(),
  };
}

Right after LogIn HomePage opens which opens ProfilePage. I do not have any special code in any of the pages the BottomNavigationBar can navigate to, I don't know if I need any. I just want the URL tom change and knew about GoRouter.

I've tried looking up tutorials but I didn't understand that much, and I've also tried using TabView but unsuccessfully.

If you have any fixes please provide them, or if there is any easier way to do the navigation part, all I want is to use tabs and the URL change when the Tab is changed. Thanks.

0

There are 0 best solutions below