Flutter 自帶完善的路由框架,可以直接用Navigator.of(context).push(route)
打開新頁面或者用命名的方式:Navigator.of(context).pushNamed($pageName);
埋凯,然后在MaterialApp#onGenerateRoute
中寫若干個switch-case
根據(jù)頁面名稱進行分發(fā)。如此操作雖然可行糖儡,但是在頁面數(shù)量較多時,還是略微繁瑣怔匣。
有時候頁面需要外部傳參——依賴注入握联,常規(guī)的方法是:
- 在頁面Widget上添加變量
- 構造函數(shù)傳入
- 在State中
widget.something
引用 - 同時在
onGenerateRoute
中創(chuàng)建widget中調(diào)用對應的構造函數(shù)。
此方法稍顯繁瑣每瞒,并且在頁面依賴變化時金闽,又要重復這4個步驟。
如果能通過簡單的配置生成代碼剿骨,并且直接使用代芜,可以簡化源碼,節(jié)省時間并且避免出錯浓利。我先是在網(wǎng)上搜索相關的解決方案挤庇,但是沒找到钞速。因此自己動手造了這個輪子——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
對應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
,獲取對應的頁面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ù)表)也是支持的爽丹,不需要額外轉換筑煮。
依賴注入
在已注入依賴的state中import 對應的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));
總結
如此初澎,就完成了頁面表及頁面參數(shù)綁定的自動生成秸应,增減頁面和注入?yún)?shù)變得如此簡單。有問題的同學歡迎留言或者提issue碑宴,github點個贊??