Flutter提供了一个完整的系统,用于在屏幕之间导航和处理深度链接。没有复杂深度链接的小应用程序可以使用Navigator,而有特定深度链接呵呵导航要求的应用程序也应该使用Router来正确处理Android和iOS上的深度链接,并在应用运行时与地址栏保持同步。
要配置您的Android或iOS应用程序以处理深层链接,
使用Navigator
Navigator小部件适用于目标平台的正确过渡动画将屏幕显示为堆栈。要导航路由的BuildContext访问Navigator并调用命令式方法,例如push()或pop():
onPresssed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SongScreen(song: song),
),
);
},
child: Text(song.name),
因为Navigator保留了一堆Route对象(代表历史堆栈),所以push()方法也接受了一个Route对象。MatereialPageRoute对象是Route的子类,它指定Material Design的过渡动画。
使用命名路由
注意:我们不建议对大多数应用程序使用命名路由。
具有简单导航和深度链接要求的应用程序可以使用Navigator导航和MaterialApp.routes深度链接的参数:
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/': (context) => HomeScreen(),
'/details': (context) => DetailScreen(),
}
);
}
此处指定的路由称为命令路路由。有关完整示例,请遵循Flutter Cookbook 中的使用命名路由导航配方。
限制
尽管命名路由可以处理深层链接,但行为始终相同且无法自定义。当平台接收到新的深度链接时,Route无论用户当前身在何处,Flutter都会将一个新的深度链接推送到Navigator上。
Flutter也不支持使用命名路由的应用程序的浏览器转发按钮。由于这些原因,我们不建议在大多数应用程序中使用命名路由。
使用路由器
具有高级导航和路由要求的Flutter应用程序(例如随时用直接链接到每个屏幕的Web应用程序,或具有多个Navigator小部件的应用程序)应该使用路由包,例如go_router,它可以解析路由路径并在任何时候配置Navigator应用收到一个新的深层链接。
要使用路由器,请切换到MaterialApp或CupertinoApp上的路由器构造函数,并为其提供路由器配置。路由包,例如go_router,通常会为您提供配置。例如:
MaterialApp.router(
routerConfig: GoRouter(
// ...
)
);
因为像go_router这样的包是声明性的,所以当收到深层链接时候,它们将始终显示相同的屏幕。
高级开发人员注意事项:如果您不想使用路由包并希望完全控制应用程序中的导航和路由,请覆盖`RouteIngomationParser`和`RouterDelegate`。当应用程序中的状态发生变化时,您可以通过`Navigator.pages`单数提供`Page`对象列表来精确控制屏幕堆栈。
一起使用Router和Navigator
Router和Navigator旨在协同工作。您可以使用Router API通过声明性路由包(例如go_router)进行导航,或者通过调用Navigator上的命令式方法(例如push()和pop())。
当您使用过Routere或声明性路由包进行导航时,Navigator上的每个路由页面支持的,这意味着它是使用Navigator构造函数上的pages参数从Page创建的。相反,通过调用Navigator.push或showDialog创建的任何Route都会向Navigator添加一个无页路由。如果您使用的是路由包,则页面支持的路由始终是可深度链接的,而无页路由则不是。
当从Navigator中删除page-backed Route时,它之后的所有pageless routes也将被删除。例如,如果深层链接通过从导航器中删除页面支持的路由来导航,则之后(直到下一个_page-backed路由)之后的所有无页面_routes也将被删除。
注意:您不能使用`WillPopScope`阻止从页面支持的屏幕导航。相反,您应该查阅路由包的API文档。
Web支持
使用该类的应用程序Router与浏览器历史API集成,以在使用浏览器的后退和前进按钮时提供一致的体验。每当您使用导航Router时,都会将一个History API条目添加到浏览器历史堆栈中。按下后退按钮使用反向时间顺序导航,这意味着用户将被逮到使用显示的先前访问过的Router的位置。这意味着如果用户从中弹出后一个页面,然后按下浏览器后退按钮,则上一个页面将被推回到推展中。