DEV Community

Cover image for Navigation in Flutter
Newton Munene
Newton Munene

Posted on

Navigation in Flutter

Prerequisites

All applications, complex and simple, need some form of navigation. It improves the general user experience. There are different approaches to navigation and one of the most popular among mobile apps is stacks. Flutter also uses this concept of poping and pushing pages onto a stack.

You will need to have basic knowledge of:

  1. Dart
  2. Widgets(Stateful and Stateless)

Named Routes

If you are a developer coming from Web development, mostly angular and react you will be familiar with route navigation. Flutter also offers this option and I find it much easier to use as the syntax is much cleaner.

You will need to define your routes in the MaterialApp widget. The routes argument takes a Map of a String as key and a WidgetBuilder as value

import 'package:flutter/material.dart';

main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        "/": (BuildContext context) => StartPage(),
        "/login": (BuildContext context) => LoginPage(),
        "/register": (BuildContext context) => RegisterPage(),
        "/home": (BuildContext context) => HomePage(),
      },
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

CAVEAT: When you specify the root route ("/") you should not specify the home widget.

You can then call Navigator.pushNamed(BuildContext context, String routeName) or Navigator.of(BuildContext context).pushNamed(String routeName)
This will add a new page to the top of the stack.

import 'package:flutter/material.dart';

class StartPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: RaisedButton(
            child: Text(
              'Go To Home Page',
            ),
            onPressed: () {
              Navigator.pushNamed(context, "/home");
            },
          ),
        ),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

To go back to the previous page you can call Navigator.pop(BuildContext context) or Navigator.of(BuildContext context).pop()
You can also use Navigator.pushReplacementNamed(BuildContext context, String routeName) to clear the stack and push a new page onto it. This means that you can't go back.
Here are some more code samples:

Navigator.pushNamed(BuildContext context, String "/home");
Navigator.of(BuildContext context).pushNamed(String routeName);

Navigator.pushReplacementNamed(BuildContext context, String routeName);
Navigator.of(BuildContext context).pushpushReplacementNamedNamed(String routeName);

Navigator.pop(BuildContext context);
Navigator.of(BuildContext context).pop();
Enter fullscreen mode Exit fullscreen mode

onGenerateRoute

An alternative to having a routes argument in your MaterialApp widget would be onGenerateRoute. This generates your routes dynamically.

import 'package:flutter/material.dart';

main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        switch (settings.name) {
          case '/':
            return MaterialPageRoute(builder: (context) => StartPage());
            break;
          case '/home':
            return MaterialPageRoute(builder: (context) => HomePage());
            break;
        }
      },
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

You can then navigate just like named routes.

Navigator.pushNamed(BuildContext context, String "/home");
Enter fullscreen mode Exit fullscreen mode

MaterialPageRoute

You don't need to have your routes defined to use this method. Because I'm from a Web background I prefer the former method but this one is also important.

import 'package:flutter/material.dart';

class StartPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: RaisedButton(
            child: Text(
              'Go To Home Page',
            ),
            onPressed: () {
              Navigator.push(
                  BuildContext context,
                   MaterialPageRoute(
                      builder: (context) =>  HomePage()));
            },
          ),
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Just as Named routes you can also call pop to go back in the stack and pushReplacement to clear the stack and add a page as the top of stack.

Navigator.push(BuildContext context,MaterialPageRoute(builder: (context) =>  
HomePage(),),);
Navigator.pushReplacement(BuildContext context,  MaterialPageRoute(builder: (context) =>  
HomePage(),),);
Navigator.pop(BuildContext context);
Enter fullscreen mode Exit fullscreen mode

That's about it for the basics. Flutter takes care of page transition animations for Android and IOS so you can focus on the important parts. In future posts I will cover:

  1. Custom page transitions
  2. Passing data back and forth

Thank You.

Latest comments (2)

Collapse
 
error12p profile image
Paula • Edited

Thank you, the topic of the different Navigator methods was very helpful to me, there are some differences that I was not clear about. It helped me for a project I'm doing.

Collapse
 
aliaon profile image
Ali Aon

thanks New