Flutter之导航和路由

704 阅读4分钟

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应用收到一个新的深层链接。

要使用路由器,请切换到MaterialAppCupertinoApp上的路由器构造函数,并为其提供路由器配置。路由包,例如go_router,通常会为您提供配置。例如:

MaterialApp.router(
    routerConfig: GoRouter(
        // ...
    )
);

因为像go_router这样的包是声明性的,所以当收到深层链接时候,它们将始终显示相同的屏幕。

 高级开发人员注意事项:如果您不想使用路由包并希望完全控制应用程序中的导航和路由,请覆盖`RouteIngomationParser``RouterDelegate`。当应用程序中的状态发生变化时,您可以通过`Navigator.pages`单数提供`Page`对象列表来精确控制屏幕堆栈。
 

一起使用RouterNavigator

RouterNavigator旨在协同工作。您可以使用Router API通过声明性路由包(例如go_router)进行导航,或者通过调用Navigator上的命令式方法(例如push()pop())。

当您使用过Routere或声明性路由包进行导航时,Navigator上的每个路由页面支持的,这意味着它是使用Navigator构造函数上的pages参数从Page创建的。相反,通过调用Navigator.pushshowDialog创建的任何Route都会向Navigator添加一个无页路由。如果您使用的是路由包,则页面支持的路由始终是可深度链接的,而无页路由则不是。

当从Navigator中删除page-backed Route时,它之后的所有pageless routes也将被删除。例如,如果深层链接通过从导航器中删除页面支持的路由来导航,则之后(直到下一个_page-backed路由)之后的所有无页面_routes也将被删除。

注意:您不能使用`WillPopScope`阻止从页面支持的屏幕导航。相反,您应该查阅路由包的API文档。

Web支持

使用该类的应用程序Router与浏览器历史API集成,以在使用浏览器的后退和前进按钮时提供一致的体验。每当您使用导航Router时,都会将一个History API条目添加到浏览器历史堆栈中。按下后退按钮使用反向时间顺序导航,这意味着用户将被逮到使用显示的先前访问过的Router的位置。这意味着如果用户从中弹出后一个页面,然后按下浏览器后退按钮,则上一个页面将被推回到推展中。