写路由比较容易,在 onGenerateRoute
函数中将各个页面对应的路由添加进去就可以了。但是通常onGenerateRoute
函数中返回的是 MaterialPageRoute
对象,其中有参数setting可以用于参数传递。
但是我们自己的页面是继承 StatefulWidget
或者 StatelessWidget
,这时候统一写的话参数就传不到页面中。当然可以在 onGenerateRoute
中一个一个枚举页面的情况。下面利用继承介绍另一种是方法。
1.1. 定义基本的路由类
class Routes {
static const String pageA = '/pageA';
static const String pageB = '/pageB';
static const String pageC = '/pageC';
// 外层,用于 alert,toast
static final GlobalKey<NavigatorState> rootKey = GlobalKey<NavigatorState>();
// 内层,用于页面
static final GlobalKey<NavigatorState> globalKey = GlobalKey<NavigatorState>();
}
1.2. 实现 StatelessWidget
和 StatefulWidget
的继承类,用于传参
// RootStatelessPage
abstract class RootStatelessPage extends StatelessWidget {
Object arguments;
RootStatelessPage({this.arguments});
@override
Widget build(BuildContext context) {
return Container();
}
}
// RootStatefulPage
abstract class RootStatefulPage extends StatefulWidget {
Object arguments;
RootStatefulPage({this.arguments});
@override
RootStatefulPageState createState() => RootStatefulPageState();
}
class RootStatefulPageState<T extends RootStatefulPage> extends State<T> {
@override
Widget build(BuildContext context) {
return Container();
}
}
// example 使用方法
class ExamplePage11 extends RootStatefulPage {
@override
_ExamplePage11State createState() => _ExamplePage11State();
}
class _ExamplePage11State extends RootStatefulPageState<ExamplePage11> {
@override
Widget build(BuildContext context) {
return Container();
}
}
1.3. 在 onGenerateRoute
函数中将参数附加进去
class RouteMainPage extends StatefulWidget {
@override
_RouteMainPageState createState() => _RouteMainPageState();
}
class _RouteMainPageState extends State<RouteMainPage> {
@override
Widget build(BuildContext context) {
return Material(
key: Routes.rootKey,
child: Builder(
builder: (context) {
return Navigator(
key: Routes.globalKey,
initialRoute: Routes.pageA,
onGenerateRoute: _buildRoute,
);
},
),
);
}
}
Route _buildRoute(RouteSettings settings) {
print('settings == $settings');
var pages = {
Routes.pageA: (context) => RoutePageA(),
Routes.pageB: (context) => RoutePageB(),
Routes.pageC: (context) => RoutePageC(),
};
return MaterialPageRoute(
builder: (context) {
var builder = pages[settings.name] ?? (context) => Container();
var page = builder(context);
// 附加参数
if (page is RootStatelessPage) {
page.arguments = settings.arguments;
} else if (page is RootStatefulPage) {
page.arguments = settings.arguments;
}
if (settings.isInitialRoute && page is RootStatefulPage) {
// 设置初始化特殊参数
page.arguments = {'isInitial': true, 'key1': 111};
}
return page;
},
settings: settings,
);
}
1.4. 使用
使用的时候,只需要我们的页面继承 RootStatefulPage
或者 RootStatelessPage
。调用传递参数如下:
Routes.globalKey.currentState.pushNamed(Routes.pageB, arguments: {
'pageAParams': '111',
'key2': 222,
});
获取参数的值:
class RoutePageB extends RootStatefulPage {
@override
_RoutePageBState createState() => _RoutePageBState();
}
class _RoutePageBState extends RootStatefulPageState<RoutePageB> {
@override
void initState() {
print('in pageB: ${widget.arguments}');
super.initState();
}
@override
Widget build(BuildContext context) {
return Container()
}
1.5. 更新补充
上面获取参数的方法整体有些复杂,有一种更方便的,不需要继承的上面Root的方案。
configParams(ModalRoute.of(context).settings.arguments);
1.6. 总结
全局路由统一管理,可以在中间件或者逻辑代码中进行页面的跳转。这样隔离了各个页面之间的依赖关系。