Flutter 路由——頁面表及頁面參數(shù)綁定的自動生成

Flutter 自帶完善的路由框架,可以直接用Navigator.of(context).push(route)打開新頁面或者用命名的方式:Navigator.of(context).pushNamed($pageName);,然后在MaterialApp#onGenerateRoute中寫若干個switch-case根據(jù)頁面名稱進行分發(fā)。如此操作雖然可行,但是在頁面數(shù)量較多時,還是略微繁瑣。

有時候頁面需要外部傳參——依賴注入,常規(guī)的方法是:

  1. 在頁面Widget上添加變量
  2. 構(gòu)造函數(shù)傳入
  3. 在State中widget.something引用
  4. 同時在onGenerateRoute中創(chuàng)建widget中調(diào)用對應(yīng)的構(gòu)造函數(shù)。

此方法稍顯繁瑣,并且在頁面依賴變化時,又要重復(fù)這4個步驟。
如果能通過簡單的配置生成代碼,并且直接使用,可以簡化源碼,節(jié)省時間并且避免出錯。我先是在網(wǎng)上搜索相關(guān)的解決方案,但是沒找到。因此自己動手造了這個輪子——router_generator
pub, github.

使用

安裝

dev_dependencies:
  router_generator: 0.1.1
  build_runner:

引用

import 'package:router_generator/router_generator.dart';

頁面標記

@Router('third')
class ThirdPage extends StatefulWidget {

在頁面Widget上使用Router注解,頁面名作為參數(shù)

參數(shù)標記

@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有兩個可選的參數(shù):

  • key: 此參數(shù)在參數(shù)表中的鍵,默認用變量名
  • required:是否必須,如果是的話,在依賴注入時,如果參數(shù)表中沒有此參數(shù),debug模式下會報錯,并且在生成的createRouteArgs方法中此參數(shù)為必須。

如果兩個參數(shù)都不需要,建議用routerParam注解。
從例子中可以看到,dart的各種類型包括自定義的model都是支持的。

代碼生成

執(zhí)行命令:flutter packages pub run build_runner build, 更多使用方法可參考 build_runner

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

  • 頁面路由表 main.router_table.dart
  • 頁面依賴注入 $page.inject.dart 若干個,其中 page 是你 state所在 文件的名稱,例如 foo.dart對應(yīng)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方法,調(diào)用main.router_table.dart中的getWidgetByPageName,獲取對應(yīng)的頁面Widget,并且deliverParams()傳遞參數(shù)。

對于嵌入原有原生的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>類型的參數(shù)表(即uri中值為字符串的參數(shù)表)也是支持的,不需要額外轉(zhuǎn)換。

依賴注入

在已注入依賴的state中import 對應(yīng)的inject文件,在使用變量前注入依賴,如:

@override
void initState() {
    super.initState();
    injectDependencies(this);
    doSometing();
}

傳遞依賴


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

可以手動創(chuàng)建依賴的參數(shù)表,但建議使用 inject 文件中的 createRouteArgs方法。

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

總結(jié)

如此,就完成了頁面表及頁面參數(shù)綁定的自動生成,增減頁面和注入?yún)?shù)變得如此簡單。有問題的同學(xué)歡迎留言或者提issue,github點個贊??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容