Skip to content

This is an example app showing how to implement bottom navigation with nested routes using go_router and cubit

Notifications You must be signed in to change notification settings

MohanedZekry/flutter-go-router-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go_router example

The purpose of the go_router package is that it is A declarative routing package for Flutter that uses the Router API to provide a convenient, url-based API for navigating between different screens and reduce complexity, regardless of the platform you're targeting (mobile, web, desktop), You can define URL patterns, navigate using a URL, handle deep links, and a number of other navigation-related scenarios.

This is an example app showing how to implement bottom navigation with nested routes using go_router and cubit

Table of Contents

Requirements

Intro

This example is built using go_router 6.2.0. Navigating bottom navbar screens with go_router. Instead of using buildBody and currentIndex for routing, we’ll be using go router to navigate between screens.

Screenshots

Screenshot 1 Screenshot 2 Screenshot 3

Implementation

To implement bottom navigation with go_router it's not simple or easy, but you can follow this instructions and everything will be just fine.

First we need to configure our routing for navigation we will use ShellRoute it displays a UI shell around the route, Follow the implelemenation to understand it.

class AppRouter {

  static final _rootNavigatorKey = GlobalKey<NavigatorState>();
  static final _shellNavigatorKey = GlobalKey<NavigatorState>();

  static final GoRouter _router = GoRouter(
    initialLocation: Routes.homeNamedPage,
    debugLogDiagnostics: true,
    navigatorKey: _rootNavigatorKey,
    routes: [
      ShellRoute(
        navigatorKey: _shellNavigatorKey,
        builder: (context, state, child) {
          return BlocProvider(
            create: (context) => NavigationCubit(),
            child: MainScreen(screen: child),
          );
        },
        routes: [
          GoRoute(
            path: Routes.homeNamedPage,
            pageBuilder: (context, state) =>
            const NoTransitionPage(
              child: HomeScreen(),
            ),
            routes: [
              GoRoute(
                path: Routes.homeDetailsNamedPage,
                builder: (context, state) => const HomeDetailsScreen(),
              ),
            ],
          ),
          GoRoute(
            path: Routes.profileNamedPage,
            pageBuilder: (context, state) =>
            const NoTransitionPage(
              child: ProfileScreen(),
            ),
            routes: [
              GoRoute(
                path: Routes.profileDetailsNamedPage,
                builder: (context, state) => const ProfileDetailsScreen(),
              ),
            ],
          ),
          GoRoute(
            path: Routes.settingsNamedPage,
            pageBuilder: (context, state) =>
            const NoTransitionPage(
              child: SettingScreen(),
            ),
          ),
        ],
      ),
    ],
    errorBuilder: (context, state) => const NotFoundScreen(),
  );
  
  static GoRouter get router => _router;
}

Notes ShellRoute has multiple routes whose returns a widget and that is child attribute to shellRoute builder.

  • after that we will implement our Cubit
class NavigationState extends Equatable {

  final String bottomNavItems;
  final int index;

  const NavigationState({required this.bottomNavItems, required this.index});

  @override
  List<Object> get props => [bottomNavItems, index];
}
  • we building three screens in the bottom navigation
enum BottomNavItems {
  home,
  profile,
  settings
}
  • our Cubit
part 'navigation_state.dart';

class NavigationCubit extends Cubit<NavigationState> {
  NavigationCubit() : super(const NavigationState(bottomNavItems: Routes.homeNamedPage, index: 0));

  void getNavBarItem(int index) {
    switch (index) {
      case 0:
        emit(const NavigationState(bottomNavItems: Routes.homeNamedPage,index:  0));
        break;
      case 1:
        emit(const NavigationState(bottomNavItems: Routes.profileNamedPage,index:  1));
        break;
      case 2:
        emit(const NavigationState(bottomNavItems: Routes.settingsNamedPage,index:  2));
        break;
    }
  }
}
  • simple bottom navigation bar
BottomNavigationBar(
          onTap: (value) {
            if(state.index != value){
              context.read<NavigationCubit>().getNavBarItem(value);
              context.go(tabs[value].initialLocation);
            }
          },
          showSelectedLabels: false,
          showUnselectedLabels: false,
          elevation: 0,
          backgroundColor: Colors.black,
          unselectedItemColor: Colors.white,
          selectedIconTheme: IconThemeData(
            size: ((IconTheme
                .of(mContext)
                .size)! * 1.3),
          ),
          items: tabs,
          currentIndex: state.index,
          type: BottomNavigationBarType.fixed,
        );

Why?

Reason being it’s now under the wing of official Flutter packages and not to mention its simplicity and good documentation.

For scenarios like this GoRouter has a new type of route called ShellRoute. ShellRoute is a route that displays a UI shell around the route. You’ll instinctively understand about shellRoute once you view this project.

About

This is an example app showing how to implement bottom navigation with nested routes using go_router and cubit

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published