- What is route_generator
- features
- Rely on
- The generated code
- route_annotation
- Code sample
- Define routing App
- Defining the routing page
- Define routing page parameters
- Custom route (Priority: 3)
- Custom route (Priority: 2)
- Custom route (Priority: 1)
- The routing code is automatically generated from the dependency packages in the pubspec.yaml file
- Questions about build_Runner Watch mode
- Matters needing attention
- Final generated code
- Q&A
- Example
Repository
What is route_generator
This is a simple library for generating Flutter routes. It requires only a small amount of code. Then annotations are combined with source code generation to automatically generate routing tables, eliminating the need to manually manage the routing code.
features
- User-defined route name
- Custom route animation
- Customize route parameters
- Custom routing logic
- Support automatic generation of routing codes from dependent packages in pubspec.yaml files
Rely on
dependencies:
# Your other regular dependencies here
route_annotation: ^ 0.2.0
dev_dependencies:
# Your other dev_dependencies here
build_runner: ^ 1.5.0
route_generator: ^ 0.1.4
Copy the code
The generated code
-
A single building
Run the flutter pub run build_runner build in the project root directory to generate routing code for the project if needed. This triggers a one-time build that traverses the source files, selects the relevant files, and generates the necessary routing code for them. While this is convenient, if you don’t have to build manually every time you make a change in a model class, you can choose to build continuously.
-
Continue to build
Start watcher by running flutter pub run build_runner watch in the project root directory to make our source code generation process much easier. It monitors changes in the project files and automatically builds the necessary files as needed.
route_annotation
annotation | description |
---|---|
Router |
This annotation identifies a class that is a Flutter App and generates the corresponding routing code |
RoutePage |
This annotation is used to annotate a routing page |
RouteParameter |
An annotation to mark page parameters, designed for optional parameters only. Used forRoutePage 。 |
RouteField |
This annotation is used to mark a fully custom route. The annotated object must be a static field of the route page class |
PageRouteBuilderFuntcion |
This annotation identifies a routing pageRouteFactory A static method |
RoutePageBuilderFunction |
This annotation identifies a routing pageRoutePageBuilder A static method |
RouteTransitionBuilderFunction |
This annotation identifies a routing pageTransitionBuilder A static method |
RouteTransitionDurationField |
This annotation identifies the transition duration of a custom routing page |
router new |
withRouter() The same |
page new |
withRoutePage() The same |
initialPage new |
withRoutePage(isInitialRoute: true) The same |
routeField new |
withRouteField() The same |
routeBuilder new |
withPageRouteBuilderFuntcion() The same |
pageBuilder new |
withRoutePageBuilderFunction() The same |
transitionBuilder new |
withRouteTransitionBuilderFunction() The same |
transitionDuration new |
withRouteTransitionDurationField() The same |
Code sample
Define routing 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, ); }}Copy the code
Defining the routing page
@initialPage
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
returnScaffold(); }}Copy the code
Define routing page parameters
-
For a single parameter
@RoutePage(params: [RouteParameter("title")]) class OneArgumentPage extends StatelessWidget { final String title; const OneArgumentPage({Key key, this.title}) : super(key: key); @override Widget build(BuildContext context) { returnContainer(); }}Copy the code
navigation
Navigator.of(context).pushNamed( ROUTE_ONE_ARGUMENT_PAGE, arguments: "title is empty",);Copy the code
Matters needing attention:
For single-parameter routes, arguments are the original arguments for navigation using Navigator.
-
For multiple parameters
@RoutePage(params: [RouteParameter("title"), RouteParameter("subTitle")]) class TwoArgumentPage extends StatelessWidget { final String title; final String subTitle; TwoArgumentPage({this.title, Key key, this.subTitle}) : super(key: key); @override Widget build(BuildContext context) { returnScaffold(); }}Copy the code
navigation
Navigator.of(context).pushNamed( ROUTE_TWO_ARGUMENT_PAGE, arguments: { "title": _titleController.text.isNotEmpty ? _titleController.text : "title is empty"."subTitle": _subTitleController.text.isNotEmpty ? _subTitleController.text : "sub title is empty",});Copy the code
Matters needing attention:
For routes with multiple parameters, arguments must be Map
,dynamic>
for navigation using Navigator.
If you don’t need a custom route, you don’t need to add anything in the following sections and let route_generator generate the code for you.
Custom route (Priority: 3)
This route has the highest priority. If multiple user-defined routes exist at the same time, this route is selected first.
@page
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(), ), }; . }Copy the code
It generates the following code:
Map<String, RouteFactory> _customRoutePage = CustomRoutePage.route;
Copy the code
Custom route (Priority: 2)
In this method, user-defined routes have a lower priority. If multiple user-defined routes exist at the same time, the routes are selected in descending order of priority.
@page
class CustomRoutePage extends StatelessWidget {
@pageBuilder
staticRoute buildPageRoute(RouteSettings settings) => PageRouteBuilder( pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) => CustomRoutePage(), ); . }Copy the code
It generates the following code:
Map<String, RouteFactory> _customRoutePage = <String, RouteFactory>{
'custom_route_page': CustomRoutePage.buildPageRoute,
};
Copy the code
Custom route (Priority: 1)
In this method, the user-defined routes have the lowest priority. If multiple user-defined routes exist at the same time, the routes are selected in descending order of priority.
@page
class CustomRoutePage extends StatelessWidget {
// The pageBuilder annotation indicates that this method is used to define how to return a RoutePage
// It is optional
@pageBuilder
static Widget buildPage(BuildContext context, Animation animation,
Animation secondaryAnimation, RouteSettings settings) =>
CustomRoutePage();
// The transitionBuilder annotation indicates that this method is used to define how to apply animation transitions
// It is optional
@transitionBuilder
static Widget buildTransitions(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
RouteSettings settings) =>
child;
The transitionDuration annotation indicates that this field is used to define how long the page will be. The default is 300 milliseconds
// It is optional
@transitionDuration
static Duration transitionDurations = Duration(milliseconds: 400); . }Copy the code
It generates the following code:
Map<String, RouteFactory> _customRoutePage = <String, RouteFactory>{
'custom_route_page': (RouteSettings settings) => PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) =>
CustomRoutePage.buildPage(
context, animation, secondaryAnimation, settings),
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
CustomRoutePage.buildTransitions(
context, animation, secondaryAnimation, child, settings),
transitionDuration: CustomRoutePage.transitionDurations,
),
};
Copy the code
The routing code is automatically generated from the dependency packages in the pubspec.yaml file
-
Create a new build.yaml file in the project root that needs to support automatic generation of routing code from dependencies in the pubspec.yaml file, skip this step if it already exists.
-
Add the following to the file:
# If you are sure that you only run `flutter pub run build_runner build`, # and don't run `flutter pub run build_runner watch`, then you can enable # the following comment out content. # targets: # $default: # builders: # route_generator|route_collector: # enabled: false # If you also want to enable source code generation for the packages of # dependencies in the pubspec.yaml, I think the following is what you need. builders: route_collector_all_packages: import: 'package:route_generator/builder.dart' builder_factories: ['routeCollectorAllPackages'] build_extensions: { '.dart': ['.collector_all_packages.dart'] } auto_apply: all_packages runs_before: ["route_generator|route_builder"] build_to: cache Copy the code
Notice Merge the same key parts.
-
Rerun build_runner command
For more information, see Example
Questions about build_Runner Watch mode
-
Pubspec. yaml Dependencies Packages does not support continuous generation of routing code in Watch mode, but you can still enable watch mode in the current application. Post consideration support.
-
Since BuildStep does not support different outputs from the same file, that is, for each file, its output file is limited, so in Watch mode, if you modify the annotation information, you may need to refresh the file with the Route annotation once (you must make the file change and save, for example, adding blank lines). Dart will be regenerated. We are trying our best to solve it. The current scheme needs to be updated manually. If you have a better scheme, welcome to put forward.
Matters needing attention
- Only one initalRoute is allowed
- InitalRoute ignores the custom route name but generates a route name
ROUTE_HOME
Route name constant of. - All custom route methods or getters must be defined in the route class and must be static and non-private.
Final generated code
Dart where FILENAME is the FILENAME of the App class annotated by the Router.
// GENERATED CODE - DO NOT MODIFY BY HAND
/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// RouteGenerator
/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
import 'package:flutter/material.dart';
import 'package:example_library/example_library.dart';
import 'package:example/custom_route_name_page.dart';
import 'package:example/custom_route_page.dart';
import 'package:example/home_page.dart';
import 'package:example/one_arguement_page.dart';
import 'package:example/two_arguement_page.dart';
import 'package:example/second_page.dart';
const ROUTE_LIBRARY_PAGE = 'library_page';
const ROUTE_CUSTOM = 'custom';
const ROUTE_CUSTOM_ROUTE_PAGE = 'custom_route_page';
const ROUTE_HOME = '/';
const ROUTE_ONE_ARGUMENT_PAGE = 'one_argument_page';
const ROUTE_TWO_ARGUMENT_PAGE = 'two_argument_page';
const ROUTE_SECOND_PAGE = 'second_page';
RouteFactory onGenerateRoute = (settings) => Map.fromEntries([
..._libraryPage.entries,
..._custom.entries,
..._customRoutePage.entries,
..._home.entries,
..._oneArgumentPage.entries,
..._twoArgumentPage.entries,
..._secondPage.entries,
])[settings.name](settings);
Map<String, RouteFactory> _libraryPage = <String, RouteFactory>{
'library_page': (RouteSettings settings) => MaterialPageRoute(
builder: (BuildContext context) => LibraryPage(),
),
};
Map<String, RouteFactory> _custom = <String, RouteFactory>{
'custom': (RouteSettings settings) => MaterialPageRoute(
builder: (BuildContext context) => CustomRoutePageName(),
),
};
Map<String, RouteFactory> _customRoutePage = CustomRoutePage.route;
Map<String, RouteFactory> _home = <String, RouteFactory>{
'/': (RouteSettings settings) => MaterialPageRoute(
builder: (BuildContext context) => HomePage(),
),
};
Map<String, RouteFactory> _oneArgumentPage = <String, RouteFactory>{
'one_argument_page': (RouteSettings settings) => MaterialPageRoute(
builder: (BuildContext context) =>
OneArgumentPage(title: settings.arguments),
),
};
Map<String, RouteFactory> _twoArgumentPage = <String, RouteFactory>{
'two_argument_page': (RouteSettings settings) => MaterialPageRoute(
builder: (BuildContext context) {
final arguments = settings.arguments as Map<String.dynamic>;
return TwoArgumentPage(
title: arguments['title'],
subTitle: arguments['subTitle']); })};Map<String, RouteFactory> _secondPage = <String, RouteFactory>{
'second_page': (RouteSettings settings) => MaterialPageRoute(
builder: (BuildContext context) => SecondPage(),
),
};
Copy the code
Q&A
-
No routing file was generated
Check that the Router annotations are added
-
Route generation is incomplete
Try running the following command:
- flutter pub run build_runner clean
- flutter pub run build_runner build
Example
For more information, see Example