Learning Routes in Flutter
Get pro in named routes in Flutter

Highly Motivated, skilled individual with a driving passion for programming and innovation. Grounded and a solution oriented, love to work in challenging environment. I always try to keep myself updated with new emerging technologies and learn them. My intrests lies in Mathematics and Computing, always try to connect software and hardware through IOT. I always love to share my knowledge to others.
Flutter is an open source framework by Google for building beautiful, natively compiled, multi-platform applications from a single codebase.
In this article, we are going to learn about routing in Flutter, how we can navigate from one screen to another, with custom arguments, simple clean and reusable code, in structured format
I am assuming you already know basics of Flutter (create simple widgets, functions and classes.). We are specifically going to see how to use named routes, and learn how to use them in managing routes easily!
Below is the GitHub link, you can follow each step using this repository.
https://github.com/Sarthak-ONS/simple-routing.git
After removing the initial written code by Flutter, lets start.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: Text("Learn Routing"),
);
}
}
Lets us make three simple different screen and learn routing from them. Create a new Folder and add three separate files for three screens respectively.
Note: you can name these files as per your choice
We are going to make a button widget and put it in a separate file, this button widget is used for navigating to different screens.
This button widget takes two parameters- 1. Title of Button 2. On tap Callback.
Lets make this button widget
import 'package:flutter/material.dart';
class MyCustomButton extends StatelessWidget {
const MyCustomButton({
Key? key,
required this.title,
required this.onTapFunction,
}) : super(key: key);
final String title;
final Function onTapFunction;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onTapFunction();
},
child: Center(
child: Container(
margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 20.0),
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20.0),
decoration: const BoxDecoration(
color: Color(0xff263F59),
borderRadius: BorderRadius.all(
Radius.circular(15.0),
),
),
child: Text(
title,
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
);
}
}
Lets now make our first screen with basic widgets like App Bar and two custom built button at the center of the screens.
import 'package:flutter/material.dart';
import '../custom_button_widget.dart';
class Screen1 extends StatelessWidget {
const Screen1({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: const Color(0xff263F59),
title: const Text('First Screen'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MyCustomButton(
onTapFunction: () {
print("Navigate to Screen 2");
},
title: "Screen 2",
),
MyCustomButton(
onTapFunction: () {
print("Navigate to Screen 3");
},
title: "Screen 3",
),
],
),
);
}
}
Now, our first Screen looks like this -

Similarly we will make our second and third screen.
Note : Please change title of App Bar and Custom Buttons accordingly to avoid any errors.


Please, check the source code on GitHub for any kinds of errors and problems.
Now, we will create a Route Generator File and add all our route in in it. Lets see how we can do it.
First create a new file, then add a Route Generator Class and add two methods in it, First method, will return a Material Page Route to a specific Screen and second method will return a error Screen, if in case there occurs any error we can return that screen.
We are using named route, using Route Settings we can get the name of each called route.
Note : We are repeating code for now, but in later section we will remove this repeating code
import 'package:flutter/material.dart';
import 'package:simple_routing/Screens/screen_one.dart';
import 'package:simple_routing/Screens/screen_two.dart';
import 'package:simple_routing/Screens/screen_third.dart';
class RouteGenerator {
Route<dynamic> generateRoute(RouteSettings routeSettings) {
switch (routeSettings.name) {
case '/':
return MaterialPageRoute(builder: (_) => const Screen1());
case '/second':
return MaterialPageRoute(builder: (_) => const Screen2());
case '/third':
return MaterialPageRoute(builder: (_) => const Screen3());
default:
return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(
builder: (_) => Scaffold(
appBar: AppBar(
title: const Text('Error'),
),
body: const Center(
child: Text('Please try again later'),
),
),
);
}
}
Now, we will add this generateRoute Method to our material App widget in main.dart file. We will remove "home" parameter in Material App and pass a initial Screen Route to "initialRoute" parameter, we will give '/' as a initialRoute parameter's value, which corresponds to First Screen in our generateRoute Method of Route Generator Class.
import 'package:flutter/material.dart';
import 'package:simple_routing/route_generator.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/',
onGenerateRoute: RouteGenerator().generateRoute,
);
}
}
Lets, start navigating using Route generator class. Now, go to screen1, and in onTapCallback of Screen2's button, navigate to screen2. Similarly, on tapCallback of Screen3's button, navigate to Screen3. We are going to use Navigator.pushNamed() method to navigate between screens.
MyCustomButton(
onTapFunction: () {
Navigator.pushNamed(context, '/second');
},
title: "Screen 2",
),
MyCustomButton(
onTapFunction: () {
Navigator.pushNamed(context, '/third');
},
title: "Screen 3",
),
Now, you may add named route in callbacks of buttons of Screen2 and Screen3 respectively.
Note: On using Navigator.pushNamed() method, screens are added to the stack, it means next screen are added to top of current screen, You can use Navigator.popAndPushNamed() to remove current screen from stack and then push to next screen.
I hope you will now be able to route between different screens!.
We can also check error Route, passing wrong arguments in Navigator.pushNamed() method, or not passing any value in method that does not corresponds to mentioned names in Route generator Class.
Lastly, we can also avoid using the "MaterialPageRoute(builder: (_) => const Screen1())" again and again in Route Generator Class by making a new method, that takes a widget in in its parameter and returns a Material Page Route.
import 'package:flutter/material.dart';
import 'package:simple_routing/Screens/screen_one.dart';
import 'package:simple_routing/Screens/screen_two.dart';
import 'package:simple_routing/Screens/screen_third.dart';
class RouteGenerator {
Route<dynamic> generateRoute(RouteSettings routeSettings) {
switch (routeSettings.name) {
case '/':
return getMaterialPageRoute(const Screen1());
case '/second':
return getMaterialPageRoute(const Screen2());
case '/third':
return getMaterialPageRoute(const Screen3());
default:
return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(
builder: (_) => Scaffold(
appBar: AppBar(
title: const Text('Error'),
),
body: const Center(
child: Text('Please try again later'),
),
),
);
}
MaterialPageRoute getMaterialPageRoute(Widget widget) {
return MaterialPageRoute(builder: (_) => widget);
}
}
Thus we can avoid repeating code, increase code reusability. We don't have to use "Navigator.push(context, MaterialPageRoute(builder: (context) =>widget()),);" route Function again and again and avoid import screens in each file. Our code looks clean and way better now.
Please check the GitHub repository for complete code.
I hope this article have created some help for you! Please share it with other developers
