route_generator 0.1.5

  • Readme
  • Changelog
  • Installing
  • 65

build_state  

English 简体中文

What is it #

This is a route generation library.Only a small amount of code is required,then use the annotation to match the source code generation, automatically generate the routing table.

Features #

  • Custom route name.
  • Custom route animations.
  • Custom route parameters.
  • Custom route logic.
  • Automatically generate routing code from dependency packages in the pubspec.yaml file

Depend on it #

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

Running the code generation utility #

  • One-time code generation

    By running flutter pub run build_runner build in the project root,you generate routing code for your application whenever they are needed. This triggers a one-time build that goes through the source files, picks the relevant ones, and generates the necessary routing code for them.

    While this is convenient, it would be nice if you did not have to run the build manually every time you make changes in your routing page classes.

  • Generating code continuously

    A watcher makes our source code generation process more convenient. It watches changes in our project files and automatically builds the necessary files when needed. Start the watcher by running flutter pub run build_runner watch in the project root.

    It is safe to start the watcher once and leave it running in the background.

route_annotation #

annotationdescription
RouterThis annotation is used to mark a class that is a Flutter App and use this to generate the corresponding routing code.
RoutePageThis annotation is used to annotate a routing page
RouteParameterAn annotation used to mark page parameters is only designed for optional parameters. Used for RoutePage.
RouteFieldThis annotation is used to mark a completely custom route, and the annotated object must be used as a static field of the route page class.
PageRouteBuilderFuntcionThis annotation is used to identify the RouteFactory static method of a routing page.
RoutePageBuilderFunctionThis annotation is used to identify the RoutePageBuilder static method of a routing page.
RouteTransitionBuilderFunctionThis annotation is used to identify the TransitionBuilder static method of a routing page.
RouteTransitionDurationFieldThis annotation is used to identify the transition time of a custom routing page.
router newSame as Router()
page newSame as RoutePage()
initialPage newSame as RoutePage(isInitialRoute: true)
routeField newSame as RouteField()
routeBuilder newSame as PageRouteBuilderFuntcion()
pageBuilder newSame as RoutePageBuilderFunction()
transitionBuilder newSame as RouteTransitionBuilderFunction()
transitionDuration newSame as RouteTransitionDurationField()

Example code #

Define routing application #

@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 routing page #

@initialPage
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

Define routing page parameters #

  • For 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) {
        return Container();
      }
    }
    

    Navigation:

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

    Warning:

    For the route of a single parameter, the arguments is the raw argument when navigating with the 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) {
        return Scaffold();
      }
    }
    

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

    Warning:

    For the route of multiple parameters, the arguments must be Map<string,dynamic> when navigating with Navigator.

If you don't need custom routing, the following sections, you can add nothing, let route_generator automatically generate relevant code for you!

Custom route (priority: 3) #

This method has the highest priority for custom routing. If there are multiple custom routing options at the same time, this plan 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(),
        ),
  };

  ...

}

It will generate the following code:

Map<String, RouteFactory> _customRoutePage = CustomRoutePage.route;

Custom route (priority: 2) #

This method has a lower priority for custom routing. If there are multiple custom routing options at the same time, the plan is selected by priority from large to small.

@page
class CustomRoutePage extends StatelessWidget {
  @pageBuilder
  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': CustomRoutePage.buildPageRoute,
};

Custom route (priority: 1) #

This method has the lowest priority for custom routing. If there are multiple custom routing options at the same time, the plan is selected by priority from large to small.

@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 use animations.
  /// 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 the length of the page transition. The
  /// default value is 300 milliseconds.
  /// It is optional
  @transitionDuration
  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.buildPage(
                context, animation, secondaryAnimation, settings),
        transitionsBuilder: (context, animation, secondaryAnimation, child) =>
            CustomRoutePage.buildTransitions(
                context, animation, secondaryAnimation, child, settings),
        transitionDuration: CustomRoutePage.transitionDurations,
      ),
};

Automatically generate routing code from dependency packages in the pubspec.yaml file #

  1. In the project root directory that needs to support automatic generation of routing code from the dependencies in the pubspec.yaml file, create a new build.yaml file, skip this step if it already exists.

  2. 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
    

    Note that the same key parts should be merged.

  3. Re-run the build_runner command

For more details, please see example

About the problem in build_runner watch mode #

  • Need to know is: pubspec.yaml dependencies packages does not support watch mode to continuously generate routing code (the first generation is still valid), but you can still enable watch mode in the current application. Consider support later.

  • Since BuildStep does not support different output of the same file, that is, for each file, its output file is limited, so in watch mode, if you modify the annotation information, then you may need to refresh the file where the Route annotation is located (The file must be changed and saved, such as adding a blank line), to regenerate xxx.route.dart. We are trying our best to solve it. The current plan needs to be refreshed manually. If you have a better solution, please feel free to ask.

Warning #

  • Only one initalRoute is allowed
  • initalRoute ignores custom route name,but generates a route name constant named ROUTE_HOME.
  • All custom route methods or getters must be defined in the class of the route page and must be static and public.

Generated code #

The file name is filename.route.dart

Where filename is the file name of the Application class annotated by 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(),
      ),
};

Common problem #

  • No file generated

    Please check if the Router annotation has been added

  • The generated route is incomplete

    Please try running the following command:

    • flutter pub run build_runner clean
    • flutter pub run build_runner build

For more details, please see example

0.1.5 #

  • Output the sorted route

0.1.4+2 #

  • Update document.

0.1.4 #

  • Remove unnecessary type conversions

0.1.3+1 #

  • Fixed: the parameter list is empty.

0.1.3 #

  • Support for source code generation of packages from dependencies in the pubspec.yaml file
  • Update example.
  • Improve the source code generation process in watch mode.

0.1.2+1 #

  • Update document link.
  • Export builder classes.
  • Add travis ci script.

0.1.2 #

  • Update description.

0.1.1 #

  • Update description.

0.1.0 #

  • Release 0.1.0.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  route_generator: ^0.1.5

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:route_generator/route_generator.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
38
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
65
Learn more about scoring.

We analyzed this package on Dec 9, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.6.1
  • pana: 0.12.21
  • Flutter: 1.9.1+hotfix.6

Maintenance issues and suggestions

Support latest dependencies. (-10 points)

The version constraint in pubspec.yaml does not support the latest published versions for 1 dependency (analyzer).

Maintain an example. (-10 points)

Create a short demo in the example/ directory to show how to use this package.

Common filename patterns include main.dart, example.dart, and route_generator.dart. Packages with multiple examples should provide example/README.md.

For more information see the pub package layout conventions.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0
analyzer ^0.38.2 0.38.5 0.39.2+1
build ^1.1.5 1.2.2
flutter 0.0.0
route_annotation ^0.2.0 0.2.1
source_gen ^0.9.4+2 0.9.4+6
Transitive dependencies
args 1.5.2
async 2.4.0
charcode 1.1.2
collection 1.14.11 1.14.12
convert 2.1.1
crypto 2.1.4
csslib 0.16.1
dart_style 1.3.3
front_end 0.1.27 0.1.29
glob 1.2.0
html 0.14.0+3
js 0.6.1+1
kernel 0.3.27 0.3.29
logging 0.11.3+2
meta 1.1.7 1.1.8
node_interop 1.0.3
node_io 1.0.1+2
package_config 1.1.0
path 1.6.4
pedantic 1.9.0
pub_semver 1.4.2
sky_engine 0.0.99
source_span 1.5.5
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
vector_math 2.0.8
watcher 0.9.7+13
yaml 2.2.0
Dev dependencies
build_runner ^1.5.0
flutter_test