20 min read

Creating a Custom Route Generator in Flutter for Improved Code Organization


Creating a Custom Route Generator in Flutter for Improved Code Organization

When building larger Flutter apps, managing navigation routes within a single file can quickly become cluttered and hard to maintain. A cleaner approach is to separate the route generation logic into its own file. In this article, we’ll walk through setting up a route_generator.dart file to simplify route management, passing parameters to pages, and configuring your MaterialApp to use this custom route generator.

Step 1: Create the Custom Route Generator

First, let’s create a new file called route_generator.dart. This file will contain the generateRoute function, which takes RouteSettings and returns the appropriate route based on the specified route name.

1.1 Define route_generator.dart

In the route_generator.dart file, set up the generateRoute function to manage the routes in your app. Here’s how it looks:

// route_generator.dart

import 'package:flutter/material.dart';
import 'my_home_page.dart';
import 'settings_page.dart';
import 'my_route_settings.dart'; // Optional: Import if you have custom route settings

Route<dynamic> generateRoute(RouteSettings settings) {
  // You can pass additional arguments through settings.arguments if needed
  switch (settings.name) {
    case '/':
      return MaterialPageRoute(builder: (context) => MyHomePage());
    case '/settings':
      return MaterialPageRoute(builder: (context) => SettingsPage());
    default:
      // Fallback route in case the requested route name doesn't match
      return MaterialPageRoute(builder: (context) => MyHomePage());
  }
}

In this file:

  • generateRoute is a function that checks settings.name to determine which page to navigate to.
  • The MaterialPageRoute is used to define each route. We specify a builder for each route that constructs the appropriate widget (like MyHomePage or SettingsPage).

Note: If you want to pass arguments to these pages, you can access them using settings.arguments within the route case.

Step 2: Configure MyApp to Use the Custom Route Generator

Next, configure your main MyApp widget to use the new generateRoute function from route_generator.dart.

2.1 Import and Use the Route Generator in MyApp

Open my_app.dart (or the main file where you configure your MaterialApp) and set up MyApp to use the custom route generator:

// my_app.dart

import 'package:flutter/material.dart';
import 'route_generator.dart'; // Import the route generator

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Multilanguage App',
      initialRoute: '/',            // Default route
      onGenerateRoute: generateRoute, // Use the custom route generator
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', ''),
        const Locale('es', ''),
      ],
    );
  }
}

void main() {
  runApp(MyApp());
}

In this file:

  • onGenerateRoute: generateRoute tells MaterialApp to use the generateRoute function from route_generator.dart for all route handling.
  • initialRoute is set to '/', so the app starts at the home page.

Step 3: Define the Pages for Navigation

Now, define MyHomePage and SettingsPage widgets, if you haven’t already. These are simple StatelessWidget or StatefulWidget classes that will serve as different pages within the app.

3.1 MyHomePage Example

// my_home_page.dart

import 'package:flutter/material.dart';

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Home Page")),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.of(context).pushNamed('/settings');
          },
          child: Text("Go to Settings"),
        ),
      ),
    );
  }
}

3.2 SettingsPage Example

// settings_page.dart

import 'package:flutter/material.dart';

class SettingsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Settings Page")),
      body: Center(child: Text("Settings")),
    );
  }
}

These pages are basic but sufficient to demonstrate navigation between pages. The button in MyHomePage navigates to the SettingsPage when pressed, using Navigator.of(context).pushNamed('/settings').

Step 4: Passing Arguments (Optional)

If you need to pass arguments to a page, you can do so with settings.arguments. Here’s how:

  1. When navigating, pass arguments:

    Navigator.of(context).pushNamed(
      '/settings',
      arguments: 'Some data',
    );
    
  2. In route_generator.dart, access settings.arguments:

    case '/settings':
      final args = settings.arguments as String;
      return MaterialPageRoute(
        builder: (context) => SettingsPage(data: args),
      );
    
  3. Update SettingsPage to accept the argument:

    class SettingsPage extends StatelessWidget {
      final String data;
      SettingsPage({required this.data});
      // Use `data` in your widget as needed
    }
    

Final Thoughts

By separating the generateRoute function into route_generator.dart, you achieve:

  • Cleaner Code: MyApp no longer has to handle route definitions directly, making it easier to read and maintain.
  • Modularity: The route generator can be reused, expanded, or modified without affecting other parts of the app.

This setup is especially helpful as your app grows, allowing you to organize routes in a single, dedicated place and easily add new routes as needed. Happy coding!

Support ❤️
If you have enjoyed my content and code, do support me by buying a couple of coffees. This will enable me to dedicate more time to research and create new content. Cheers!
Share this Article
Share this article with your network to help others!
What's your Feedback?
Do let me know your thoughts around this article.