Flutter 自帶完善的路由框架,能夠直接用Navigator.of(context).push(route)
打開新頁面或者用命名的方式:Navigator.of(context).pushNamed($pageName);
,而後在MaterialApp#onGenerateRoute
中寫若干個switch-case
根據頁面名稱進行分發。如此操做雖然可行,可是在頁面數量較多時,仍是略微繁瑣。git
有時候頁面須要外部傳參——依賴注入,常規的方法是:github
widget.something
引用onGenerateRoute
中建立widget中調用對應的構造函數。此方法稍顯繁瑣,而且在頁面依賴變化時,又要重複這4個步驟。 若是能經過簡單的配置生成代碼,而且直接使用,能夠簡化源碼,節省時間而且避免出錯。我先是在網上搜索相關的解決方案,可是沒找到。所以本身動手造了這個輪子——router_generator: pub, 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
有兩個可選的參數:函數
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點個贊🤓