Skip to main content

Navigation Basics

If you've followed along from the Beginning you would have seen this code:

_navigationService.replaceWith(Routes.homeView);

Navigation is part of Stacked Services, a group of services within Stacked that helps you perform certain tasks in your code. To learn more about What a service is, read this.

The services currently included are:

  1. [Navigation Service][#navigation]
  2. Dialog Service
  3. Bottom Sheet Service
  4. Snackbar Service

...with more coming soon. In this doc we'll cover navigation.

Navigation

The NavigationService is how you navigate within a Stacked app. It's accessible in all ViewModels through the locator where you can perform your navigational tasks.

Your Views will automatically be added to app/app.dart in the section below, when using the CLI to create a View. This will generate the navigation calls for you to use:

(routes: [
MaterialRoute(page: StartupView),
MaterialRoute(page: HomeView),
MaterialRoute(page: CounterView),
// @stacked-route
])
class App {}

Perform a Navigation

There are different navigation types. Lets go through all of them and see what they do.

This is the most common navigation. This will add the View that you are navigating to onto the navigation stack. We do this by using the navigateTo[ViewName] function:

_navigationService.navigateToHomeView();

In your Stacked app generated at the beginning, open home_view.dart where we'll pass in a value to it through its constructor:

class HomeView extends StackedView<HomeViewModel> {
final int startingIndex;
const HomeView({Key? key, required this.startingIndex}) : super(key: key);
...
}

Now run stacked generate. You will notice that the navigateToHomeView call above will now have a compilation error. Since startingIndex is required, you will have to pass in the startingIndex value when navigating to the HomeView:

_navigationService.navigateToHomeView(startingIndex: 0);

Replace with View

Another popular navigation method is to replace the current View on screen with the new one, instead of adding it to the top of the navigation stack. This is done by using the replaceWith[ViewName] function and works much the same as above:

_navigationService.replaceWithHomeView(startingIndex: 0);

Back Navigation

When you want to go back one View to the previous View, you can use the back function:

_navigationService.back();

Pass Data to the Previous View

The back function also takes a result parameter. This will pass the result back to the calling function. All navigation calls return a Future so that they can all be awaited:

final result = await _navigationService.replaceWithHomeView(startingIndex: 0);
print('Returned result: $result');

Given the code above, when you call:

_navigationService.back(result: 'From back call');

It will print Returned result: From back call. The result is dynamic so you can return any object, your own class, or built in types. In addition to the basics above, there are some additional functions that make some navigation tasks easier:

  • clearStackAndShow: This will clear the entire navigation stack and then show the HomeView:
_navigationService.clearStackAndShow(Routes.homeView);

More advanced docs and tutorials for navigation are coming soon.

Custom Transitions

In Flutter the MaterialRoute and CupertinoRoute has pre-defined transitions. To supply your own transition you have to use a CustomRoute. Stacked allows you to do that. The transition can be supplied to the StackedApp to ensure any navigation to this view uses the supplied transition, or it can be supplied when navigating to the view.

Supplied at App Level

In your app.dart file when you define the route use a CustomRoute over a Material or CupertinoRoute.

(routes: [
MaterialRoute(page: StartupView),
MaterialRoute(page: HomeView),
CustomRoute(page: CounterView), // <== Custom Route
// @stacked-route
])
class App {}

The custom route allows you to supply a transition property as well. This HAS to be a static builder function. Stacked comes with pre-defined transitions which you can use. We cover the basic transitions like fadeIn, zoomIn, slideLeft, slideRight and many more under the TransitionsBuilders class. Lets use the fade for our example.

(routes: [
...
CustomRoute(
page: CounterView,
transitionsBuilder: TransitionsBuilders.fadeIn,
),
// @stacked-route
])
class App {}

Now run stacked generate and when you navigate to this view you'll see it fade in. If you want no transition (this is usually preferred on web) then remove the transition builder and only keep the CustomRoute.

Set Transition When Navigating

In addition to supplying the transition at an app level you can also supply the transition when you perform the navigation. To achieve this your route still has to be a CustomRoute to ensure that Flutter allows Stacked to build the transition you want. This does not require a regenerate of the code to get it working, only that the code has been regenerated as a CustomRoute.

  await _navigationService.navigateTo(
Routes.secondView,
transition: TransitionsBuilders.fadeIn,
);

Build Your Own Transition

The way to build the transition is quite simple. You create a class with your Transitions and inside you create a static function with the following signature. Widget Function(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) . This function will be called as the transition happens. Here's an example a transition using the Animations package.

import 'package:animations/animations.dart';
import 'package:flutter/material.dart';

class CustomRouteTransition {
static Widget sharedAxis(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {

// Here you can use any Existing Transition class in Flutter
return SharedAxisTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.scaled,
child: child,
);
}
}

This can be used as the same as the Transitions that ship with Stacked in the TransitionBuilders class.

// In app.dart
CustomRoute(
page: CounterView,
transitionsBuilder: CustomRouteTransition.sharedAxis,
),

// When navigating
await _navigationService.navigateTo(
Routes.secondView,
transition: transitionsBuilder: CustomRouteTransition.sharedAxis,
);

We're ready for the Web 🚀

Master Flutter on the web with the official Flutter Web Course