Flutter 路由——页面表及页面参数绑定的自动生成

Flutter 自带完善的路由框架,能够直接用Navigator.of(context).push(route)打开新页面或者用命名的方式:Navigator.of(context).pushNamed($pageName);,而后在MaterialApp#onGenerateRoute中写若干个switch-case根据页面名称进行分发。如此操做虽然可行,可是在页面数量较多时,仍是略微繁琐。git

有时候页面须要外部传参——依赖注入,常规的方法是:github

  1. 在页面Widget上添加变量
  2. 构造函数传入
  3. 在State中widget.something引用
  4. 同时在onGenerateRoute中建立widget中调用对应的构造函数。

此方法稍显繁琐,而且在页面依赖变化时,又要重复这4个步骤。 若是能经过简单的配置生成代码,而且直接使用,能够简化源码,节省时间而且避免出错。我先是在网上搜索相关的解决方案,可是没找到。所以本身动手造了这个轮子——router_generatorpub, github.bash

使用

安装

dev_dependencies:
  router_generator: 0.1.1
  build_runner:
复制代码

引用

import 'package:router_generator/router_generator.dart';框架

页面标记

@Router('third')
class ThirdPage extends StatefulWidget {
复制代码

在页面Widget上使用Router注解,页面名做为参数ide

参数标记

@inject
class ThirdPageState extends State<ThirdPage> {
  @RouterParam(required: true)
  Person person;
  @RouterParam(key: 'set_key')
  bool setKey = false;
  @routerParam
  Map<String, int> map;
复制代码

给须要注入依赖的State添加inject注解,而且在变量上添加RouterParam 注解RouterParam有两个可选的参数:函数

  • key: 此参数在参数表中的键,默认用变量名
  • required:是否必须,若是是的话,在依赖注入时,若是参数表中没有此参数,debug模式下会报错,而且在生成的createRouteArgs方法中此参数为必须。

若是两个参数都不须要,建议用routerParam注解。 从例子中能够看到,dart的各类类型包括自定义的model都是支持的ui

代码生成

执行命令:flutter packages pub run build_runner build, 更多使用方法可参考 build_runnerthis

生成的若干dart文件中包含:spa

  • 页面路由表 main.router_table.dart
  • 页面依赖注入 $page.inject.dart 若干个,其中 page 是你 state所在 文件的名称,例如 foo.dart对应foo.inject.dart

引用

路由生成

MaterialApp(
  ...
  onGenerateRoute: (RouteSettings settings) {
    String pageName = settings.name;
    var arguments = settings.arguments;
    if (arguments is Map<String, dynamic>) {
      deliverParams(pageName, arguments);
    }
    return MaterialPageRoute(builder: (_) {
      return getWidgetByPageName(pageName);
    });
  },
);
复制代码

修改onGenerateRoute方法,调用main.router_table.dart中的getWidgetByPageName,获取对应的页面Widget,而且deliverParams()传递参数。debug

对于嵌入原有原生的App,可参考:

onGenerateRoute: (RouteSettings settings) {
    String route = settings.name;
    Uri uri = Uri.parse(route);
    var pageName = uri.path.replaceFirst(RegExp('/'), '');
    lastRouteParams = uri.queryParameters;
    return PageRouteBuilder(pageBuilder: (BuildContext context,
        Animation<double> animation, Animation<double> secondaryAnimation) {
      return getWidgetByPageName(pageName);
    });
  },
复制代码

Map<String, String>类型的参数表(即uri中值为字符串的参数表)也是支持的,不须要额外转换。

依赖注入

在已注入依赖的state中import 对应的inject文件,在使用变量前注入依赖,如:

@override
void initState() {
	super.initState();
	injectDependencies(this);
	doSometing();
}
复制代码

传递依赖

Navigator.of(context).pushNamed('second',
                    arguments: {'name': 'bar', 'count': 666});
                    
复制代码

能够手动建立依赖的参数表,但建议使用 inject 文件中的 createRouteArgs方法。

Navigator.of(context).pushNamed('second',
                    arguments: createRouteArgs(name: 'bar', count: 666));

复制代码

总结

如此,就完成了页面表及页面参数绑定的自动生成,增减页面和注入参数变得如此简单。有问题的同窗欢迎留言或者提issue,github点个赞🤓

相关文章
相关标签/搜索