SoFunction
Updated on 2025-04-09

Flutter uses annotations to generate customizable route implementations

What is route_generator

This is a simple Flutter routing generation library that only requires a small amount of code, and then uses annotations to cooperate with source code generation to automatically generate routing tables, saving the trouble of manually managing routing code.

characteristic

  • Custom routing name
  • Custom routing animations
  • Custom routing parameters
  • Custom routing logic

rely

dependencies:
 # Your other regular dependencies here
 route_annotation: ^0.1.0

dev_dependencies:
 # Your other dev_dependencies here
 build_runner: ^1.5.0
 route_generator: ^0.1.2

Generate code

Single build

Run flutter pub run build_runner build in the project root directory to generate routing code for the project when needed. This triggers a one-time build that traverses the source files, selects related files, and generates the necessary routing code for them. While this is handy, if you don't have to build manually every time you make changes in your model class, you can choose to build continuously.

Continuous construction

Run flutter pub run build_runner watch in the project root directory to start watcher, which can make our source code generation process more convenient. It monitors changes in the project file and automatically builds necessary files if needed.

route_annotation

annotation description
Router This annotation is used to mark a class that is a Flutter App and generate the corresponding routing code.
RoutePage This annotation is used to annotate a routing page
RouteParameter An annotation used to mark page parameters is designed only for optional parameters. Used for RoutePage.
RouteField This annotation is used to mark a fully customized route, and the annotated object must be a static field of the routing page class
PageRouteBuilderFuntcion This annotation is used to identify a RouteFactory static method of a routing page
RoutePageBuilderFunction This annotation is used to identify a route page's static method
RouteTransitionBuilderFunction This annotation is used to identify a static TransitionBuilder method of a routing page.
RouteTransitionDurationField This annotation is used to identify the transition time of a custom routing page

Code Example

Define the route App

@Router()
class DemoApp extends StatefulWidget {
 @override
 _DemoAppState createState() => _DemoAppState();
}

class _DemoAppState extends State<DemoApp> {
 @override
 Widget build(BuildContext context) {
  return MaterialApp(
   initialRoute: "/",
   onGenerateRoute: onGenerateRoute,
  );
 }
}

Define the routing page

// isInitialRoute is true to indicate that it will be used as initial page@RoutePage(isInitialRoute: true)
class HomePage extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
  return Scaffold();
 }
}

Define routing page parameters

For a single parameter

@RoutePage(params: [RouteParameter("title")])
class OneArgumentPage extends StatelessWidget {
 final String title;

 const OneArgumentPage({Key key, }) : super(key: key);

 @override
 Widget build(BuildContext context) {
  return Container();
 }
}

navigation

(context).pushNamed(
 ROUTE_ONE_ARGUMENT_PAGE,
 arguments: "title is empty",
);

Notes:

For routing of single parameters, arguments are the original parameters when navigating with Navigator.

For multiple parameters

@RoutePage(params: [RouteParameter("title"), RouteParameter("subTitle")])
class TwoArgumentPage extends StatelessWidget {
 final String title;
 final String subTitle;

 TwoArgumentPage({, Key key, }) : super(key: key);

 @override
 Widget build(BuildContext context) {
  return Scaffold();
 }
}

navigation

(context).pushNamed(
 ROUTE_TWO_ARGUMENT_PAGE,
 arguments: {
  "title": _titleController.
    ? _titleController.text
    : "title is empty",
  "subTitle": _subTitleController.
    ? _subTitleController.text
    : "sub title is empty",
 },
);

Notes:

For multiple parameters routing, when using Navigator for navigation, arguments must be Map<string, dynamic>.

If you don't need to customize the route, you can add nothing in the following sections, just let route_generator automatically generate relevant code for you!

Custom routing (priority: 3)

This method has the highest priority for custom routing. If multiple custom routing options exist at the same time, this solution will be selected first.

@RoutePage()
class CustomRoutePage extends StatelessWidget {
 @RouteField()
 static Map<String, RouteFactory> route = <String, RouteFactory>{
  'custom_route': (RouteSettings settings) =>
    MaterialPageRoute(builder: (BuildContext context) => CustomRoutePage()),
  'alias_route': (RouteSettings settings) => PageRouteBuilder(
     pageBuilder: (BuildContext context, Animation animation,
         Animation secondaryAnimation) =>
       CustomRoutePage(),
    ),
 };

 ...

}

It will generate the following code:

Map<String, RouteFactory> _customRoutePage = ;

Custom routing (Priority: 2)

This method has a lower priority in custom routing. If multiple custom routing options exist at the same time, choose from large to small by priority.

@RoutePage()
class CustomRoutePage extends StatelessWidget {
 @PageRouteBuilderFuntcion()
 static Route buildPageRoute(RouteSettings settings) => PageRouteBuilder(
    pageBuilder: (BuildContext context, Animation animation,
        Animation secondaryAnimation) =>
      CustomRoutePage(),
   );

 ...

}

It will generate the following code:

Map<String, RouteFactory> _customRoutePage = <String, RouteFactory>{
 'custom_route_page': ,
};

Custom routing (priority: 1)

This method has the lowest priority for custom routing, and if multiple custom routing options are present at the same time, choose from large to small by priority.

@RoutePage()
class CustomRoutePage extends StatelessWidget {
 // RoutePageBuilderFunction annotation indicates that this method is used to define how to return RoutePage // It is optional @RoutePageBuilderFunction()
 static Widget buildPage(BuildContext context, Animation animation,
     Animation secondaryAnimation, RouteSettings settings) =&gt;
   CustomRoutePage();

 // The RouteTransitionBuilderFunction annotation shows that this method is used to define how to apply animation transitions // It is optional @RouteTransitionBuilderFunction()
 static Widget buildTransitions(
     BuildContext context,
     Animation&lt;double&gt; animation,
     Animation&lt;double&gt; secondaryAnimation,
     Widget child,
     RouteSettings settings) =&gt;
   child;

 // RouteTransitionDurationField annotation indicates that this field is used to define the long time of page transitions, with a default value of 300 million seconds // It is optional @RouteTransitionDurationField()
 static Duration transitionDuration = Duration(milliseconds: 400);

 ...

}

It will generate the following code:

Map<String, RouteFactory> _customRoutePage = <String, RouteFactory>{
 'custom_route_page': (RouteSettings settings) => PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) =>
      CustomRoutePage(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) =>
      (
        context, animation, secondaryAnimation, child, settings),
    transitionDuration: ,
   ),
};

Things to note

  • Only one initialRoute is allowed
  • initialRoute ignores the custom route name, but generates a route name constant named ROUTE_HOME.
  • All custom routing methods or getters must be defined in the class where the route resides and must be statically modified and non-private.

Final code generation

The final generated file name is

FILENAME is the file name of the App class annotated by Router.

// GENERATED CODE - DO NOT MODIFY BY HAND

// **************************************************************************
// RouteGenerator
// **************************************************************************

import 'package:flutter/';
import 'home_page.dart';
import 'custom_route_page.dart';
import 'custom_route_name_page.dart';
import 'second_page.dart';
import 'one_arguement_page.dart';
import 'two_arguement_page.dart';

const ROUTE_HOME = '/';
const ROUTE_CUSTOM_ROUTE_PAGE = 'custom_route_page';
const ROUTE_CUSTOM = 'custom';
const ROUTE_SECOND_PAGE = 'second_page';
const ROUTE_ONE_ARGUMENT_PAGE = 'one_argument_page';
const ROUTE_TWO_ARGUMENT_PAGE = 'two_argument_page';

RouteFactory onGenerateRoute = (settings) => ([
   ..._home.entries,
   ..._customRoutePage.entries,
   ..._custom.entries,
   ..._secondPage.entries,
   ..._oneArgumentPage.entries,
   ..._twoArgumentPage.entries,
  ])[](settings);

Map<String, RouteFactory> _home = <String, RouteFactory>{
 '/': (RouteSettings settings) => MaterialPageRoute(
    builder: (BuildContext context) => HomePage(),
   ),
};
Map<String, RouteFactory> _customRoutePage = <String, RouteFactory>{
 'custom_route_page': (RouteSettings settings) => PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) =>
      (
        context, animation, secondaryAnimation, settings),
    transitionsBuilder: (context, animation, secondaryAnimation, child) =>
      (
        context, animation, secondaryAnimation, child, settings),
    transitionDuration: ,
   ),
};
Map<String, RouteFactory> _custom = <String, RouteFactory>{
 'custom': (RouteSettings settings) => MaterialPageRoute(
    builder: (BuildContext context) => CustomRoutePageName(),
   ),
};
Map<String, RouteFactory> _secondPage = <String, RouteFactory>{
 'second_page': (RouteSettings settings) => MaterialPageRoute(
    builder: (BuildContext context) => SecondPage(),
   ),
};
Map<String, RouteFactory> _oneArgumentPage = <String, RouteFactory>{
 'one_argument_page': (RouteSettings settings) => MaterialPageRoute(
    builder: (BuildContext context) =>
      OneArgumentPage(title: ),
   ),
};
Map<String, RouteFactory> _twoArgumentPage = <String, RouteFactory>{
 'two_argument_page': (RouteSettings settings) => MaterialPageRoute(
    builder: (BuildContext context) => TwoArgumentPage(
       title: ( as Map<String, dynamic>)['title'],
       subTitle:
         ( as Map<String, dynamic>)['subTitle'],
      ),
   ),
};

Frequently Asked Questions

No routing file was generated

Please check if the Router annotation has been added

Example

For more details, seeexample

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.