在 Flutter 应用中,页面的切换跳转是非常常见的需求,这通常被称为页面导航管理。类似于原生开发,Flutter 也使用一个路由栈来管理页面的打开和关闭,通过入栈和出栈操作来实现页面的导航。
MaterialPageRoute
Flutter 默认使用 Material 组件库,对于路由切换有一个抽象类 PageRoute
,表示占据整个屏幕空间的模态路由页面。这个类定义了路由构建以及切换时过渡动画的相关接口和属性。MaterialPageRoute
继承自 PageRoute
,可以在不同平台上实现一致的页面切换动画效果。其构造函数如下:
MaterialPageRoute({
WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
})
主要参数说明:
builder
: 返回一个 WidgetBuilder
类型,用于构建路由页面的具体内容。settings
: 路由的配置信息,包括路由名称和是否为初始路由。maintainState
: 默认情况下,原来的路由页面会保存在内存中。如果希望在路由不再使用时释放其占用的资源,可以将此字段设置为 false
。fullscreenDialog
: 标识新的路由页面是否是一个全屏的模态对话框。
对于 Android 平台,打开新页面时,新页面从屏幕底部滑动至屏幕顶部,关闭时从屏幕顶部滑动至屏幕底部消失,同时上一个页面会显示到当前屏幕。对于 iOS 平台,打开页面时,新的页面会从屏幕右侧边缘滑动到屏幕左侧,直到新页面完全显示在屏幕上,而上一个页面则会从当前屏幕滑动到屏幕左侧消失。关闭页面时,当前页面会从屏幕右侧滑出,同时上一个页面会从屏幕左侧滑入。
Navigator
有了路由页面,自然需要一个工具来管理路由的打开和关闭,Navigator
就是这样一个工具。Navigator
通过一个栈来管理活动路由的集合,默认情况下,当前屏幕显示的页面为栈顶的路由页面。Navigator
使用 push
和 pop
方法来完成路由的入栈和出栈操作,方法定义如下:
Future push(BuildContext context, Route route)
bool pop(BuildContext context, [ result ])
Future
对象用于接收路由页面关闭时返回的数据。BuildContext
是构建上下文,包含 widget 构建的若干信息。Navigator.push(BuildContext context, Route route)
等价于 Navigator.of(context).push(Route route)
。
pop
方法的参数 [result]
用于在关闭路由页面时,将被关闭页面返回的数据传递给上一个页面。
路由传值
在实际开发中,我们经常需要在路由页面跳转时传递一些参数数据。以下是一个简单的示例,展示了如何在路由跳转时传递参数:
这是一个无状态的 widget,包含一个 RaisedButton
按钮。点击按钮时,使用路由导航打开第二个路由页面 TipRoute
,并通过 text
参数传递需要传递的数据。在 TipRoute
中,使用 text
接收传递的数据并展示,并通过 result
接受管理器执行出栈返回的数据,模拟打印日志记录。
TipRoute
的构建参数中使用 text
接收传递的数据并展示,同时使用 RaisedButton
组件定义一个 onPressed
事件,执行导航管理器出栈操作,将返回数据回传至移除当前路由页面关闭后位于栈顶的路由页面 RouterTestRoute
。
命名路由
命名路由是指通过路由名称直接完成路由跳转,这种方式更加直观。使用命名路由需要提供一个路由表 routing table
,定义为:
Map routes;
其中,WidgetBuilder
是管理器的回调函数,用于生成相应的路由 widget。
路由表注册
在应用的入口类中完成路由表的注册,使用 initialRoute
属性定义默认路由,实例代码中使用 /
作为默认路由页面:
注册路由表后,可以使用 Navigator
的 pushNamed
方法以路由名称跳转至指定路由页面:
Future pushNamed(BuildContext context, String routeName, {Object arguments});
命名路由也可以支持参数传递,使用 MaterialPageRoute
的 RouteSettings
获取路由参数,获取方式为:
var args = ModalRoute.of(context).settings.arguments;
传递参数时处理为:
Navigator.of(context).pushNamed("route_page_name", arguments: "some args");
路由钩子
在某些需要页面权限控制等场景下,可以使用 MaterialApp
的 onGenerateRoute
方法处理 Navigator.pushNamed
时未在路由表中注册的页面。需要注意的是,onGenerateRoute
函数仅对命名路由生效,其回调函数签名如下:
Route Function(RouteSettings settings)
实例代码:
MaterialApp(
...
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(builder: (context) {
String routeName = settings.name;
// 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,
// 引导用户登录;其它情况则正常打开路由。
});
},
);
结语
以上就是关于 Flutter 2.* 路由管理的详细介绍。如果希望了解更多关于路由处理的信息,建议多翻阅框架代码和 API 文档。如果有任何疑问,欢迎私信或加入讨论组一起讨论。