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(),
      },
    );
  }
}

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");
            },
          ),
        ),
      ),
    );
  }
}

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();

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;
        }
      },
    );
  }
}

You can then navigate just like named routes.

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

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()));
            },
          ),
        ),
      ),
    );
  }
}

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);

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.

No Comments Yet